Извлечь текст между тремя одинарными кавычками

8

У меня есть следующее в файле

description: '''
        This rule forbids throwing string literals or interpolations. While
        JavaScript (and CoffeeScript by extension) allow any expression to
        be thrown, it is best to only throw <a
        href="https://developer.mozilla.org
        /en/JavaScript/Reference/Global_Objects/Error"> Error</a> objects,
        because they contain valuable debugging information like the stack
        trace. Because of JavaScript's dynamic nature, CoffeeLint cannot
        ensure you are always throwing instances of <tt>Error</tt>. It will
        only catch the simple but real case of throwing literal strings.
        <pre>
        <code># CoffeeLint will catch this:
        throw "i made a boo boo"

        # ... but not this:
        throw getSomeString()
        </code>
        </pre>
        This rule is enabled by default.
        '''

с несколькими другими вещами в этом файле.

Я извлекаю эту часть в моем скрипте через sed -n "/'''/,/'''/p" $1(где $1находится файл).

Это дает мне переменную с содержимым как один вкладыш

description: ''' This rule forbids throwing string literals or interpolations. While JavaScript (and CoffeeScript by extension) allow any expression to be thrown, it is best to only throw <a href="https://developer.mozilla.org /en/JavaScript/Reference/Global_Objects/Error"> Error</a> objects, because they contain valuable debugging information like the stack trace. Because of JavaScript's dynamic nature, CoffeeLint cannot ensure you are always throwing instances of <tt>Error</tt>. It will only catch the simple but real case of throwing literal strings. <pre> <code># CoffeeLint will catch this: throw "i made a boo boo" # ... but not this: throw getSomeString() </code> </pre> This rule is enabled by default. '''

Как я могу теперь извлечь часть между '''?

Или есть даже лучший способ извлечь его из многострочного файла?

Я на Mac El Captain 10.11.2 и GNU bash, версия 3.2.57 (1) -релиз (x86_64-apple-darwin15)

Эмерсон Код
источник
3
Поместите двойные кавычки вокруг переменной, она содержит символы новой строки.
DisplayName
1
Это YAML, верно? По какой причине вы на самом деле не используете парсер YAML?
Чарльз Даффи
@DisplayName, ... чтобы быть понятным, вы имеете в виду двойные кавычки, когда эхо , верно?
Чарльз Даффи

Ответы:

12
perl -l -0777 -ne "print for /'''(.*?)'''/gs" file

будет извлекать (и печатать после новой строки) часть между каждой парой '' '.

Остерегайтесь, perlчтобы весь файл хранился в памяти перед началом его обработки, чтобы решение не подходило для очень больших файлов.

Стефан Шазелас
источник
7

Попробуйте это, если у вас есть gawkили mawkв вашем распоряжении:

gawk -v "RS='''" 'FNR%2==0' file

Это предполагает, что '''в файле нет других ключей.

Объяснение: Он устанавливает разделитель записей в три одинарных кавычки и печатает, если номер записи четный.

К сожалению, это не будет работать со всеми awkреализациями, так как многосимвольные разделители записей не являются частью POSIX awk.

joepd
источник
(мой) терминал Mac не знает gawk по умолчанию.
Эмерсон Код
4

Не так хорошо, как ответ на awk, но как вы изначально использовали sed

/'''/{
   s/.*'''//
   :1
   N
   /'''/!b1
   s/'''.*//
   p
}
d

Или короче, как указано Гленном Джекманом в комментариях (немного изменено)

/'''/,//{
//!p
}
d

Беги как

sed -f script file

Вывод

    This rule forbids throwing string literals or interpolations. While
    JavaScript (and CoffeeScript by extension) allow any expression to
    be thrown, it is best to only throw <a
    href="https://developer.mozilla.org
    /en/JavaScript/Reference/Global_Objects/Error"> Error</a> objects,
    because they contain valuable debugging information like the stack
    trace. Because of JavaScript's dynamic nature, CoffeeLint cannot
    ensure you are always throwing instances of <tt>Error</tt>. It will
    only catch the simple but real case of throwing literal strings.
    <pre>
    <code># CoffeeLint will catch this:
    throw "i made a boo boo"

    # ... but not this:
    throw getSomeString()
    </code>
    </pre>
    This rule is enabled by default.
123
источник
1
Вы можете сжать этот sed до sed -n "/'''/,//{//!p}"- вероятно, придется set +Hсначала сделать это в bash, чтобы отключить расширение истории.
Гленн Джекман
@glennjackman По этой причине я включил его в сценарий, IMO всегда более читабелен и так же невосприимчив к таким функциям оболочки, как глобализация, расширение и т. д. В любом случае я добавил его в свой ответ, поскольку он более лаконичен, чем мой оригинальный сценарий.
123