Extrahieren Sie Text zwischen drei einfachen Anführungszeichen

8

Ich habe folgendes in einer Datei

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.
        '''

mit mehreren anderen Dingen in dieser Datei.

Ich extrahiere diesen Teil in meinem Shell-Skript über sed -n "/'''/,/'''/p" $1(wo $1ist die Datei).

Dies gibt mir eine Variable mit dem Inhalt als ein Liner

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. '''

Wie kann ich jetzt den Teil zwischen dem extrahieren '''?

Oder gibt es noch eine bessere Möglichkeit, es aus der mehrzeiligen Datei abzurufen?

Ich bin auf Mac El Captain 10.11.2 und GNU Bash, Version 3.2.57 (1) -Veröffentlichung (x86_64-apple-darwin15)

Emerson Cod
quelle
3
Setzen Sie doppelte Anführungszeichen um die Variable, sie enthält dann Zeilenumbrüche.
Anzeigename
1
Das ist YAML, richtig? Gibt es einen Grund, warum Sie keinen YAML-Parser verwenden?
Charles Duffy
@DisplayName, ... um klar zu sein, meinst du doppelte Anführungszeichen beim Echo , oder?
Charles Duffy

Antworten:

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

würde den Teil zwischen jedem Paar von '' 'extrahieren (und drucken, gefolgt von einer neuen Zeile).

perlBeachten Sie, dass die gesamte Datei im Speicher verschluckt wird, bevor Sie mit der Verarbeitung beginnen, sodass die Lösung möglicherweise nicht für sehr große Dateien geeignet ist.

Stéphane Chazelas
quelle
7

Versuchen Sie dies, wenn Sie gawkoder mawkzu Ihrer Verfügung haben:

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

Dies setzt voraus, dass '''die Datei keine anderen -s enthält.

Erläuterung: Das Datensatztrennzeichen wird auf drei einfache Anführungszeichen gesetzt und gedruckt, wenn die Datensatznummer gerade ist.

Leider funktioniert es nicht bei allen awkImplementierungen, da Datensatztrennzeichen mit mehreren Zeichen nicht Teil von sind POSIX awk.

joepd
quelle
(mein) Mac-Terminal kennt Gawk nicht standardmäßig.
Emerson Cod
4

Nicht so schön wie die Antwort von awk, aber wie Sie ursprünglich sed verwendet haben

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

Oder kürzer, wie von Glenn Jackman in den Kommentaren hervorgehoben (leicht geändert)

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

Rennen wie

sed -f script file

Ausgabe

    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
quelle
1
Sie können das verdichten, um sed -n "/'''/,//{//!p}"- wahrscheinlich müssen Sie set +Hzuerst in Bash tun , um die Erweiterung der Geschichte auszuschalten.
Glenn Jackman
@glennjackman Das war der Grund, warum ich es in ein Skript aufgenommen habe. IMO ist es immer besser lesbar und immun gegen Shell-Funktionen wie Globbing, Erweiterung usw. Wie auch immer, ich habe es meiner Antwort hinzugefügt, da es prägnanter ist als mein ursprüngliches Skript.
123