Extraire du texte entre trois guillemets simples

8

J'ai ce qui suit dans un fichier

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

avec plusieurs autres choses dans ce fichier.

J'extrais cette partie dans mon script shell via sed -n "/'''/,/'''/p" $1(où $1est le fichier).

Cela me donne une variable avec le contenu comme une doublure

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

Comment puis-je maintenant extraire la pièce entre le '''?

Ou existe-t-il encore un meilleur moyen de le récupérer à partir du fichier multiligne?

Je suis sur Mac El Captain 10.11.2 et GNU bash, version 3.2.57 (1) -release (x86_64-apple-darwin15)

Emerson Cod
la source
3
Mettez des guillemets autour de la variable, elle contient alors des retours à la ligne.
DisplayName
1
C'est YAML, non? Une raison pour laquelle vous n'utilisez pas réellement un analyseur YAML?
Charles Duffy
@DisplayName, ... pour être clair, vous voulez dire des guillemets doubles lors de l'écho , non?
Charles Duffy

Réponses:

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

extraira (et imprimera suivi d'une nouvelle ligne) la partie entre chaque paire de '' '.

Attention, perlla totalité du fichier est stockée en mémoire avant de commencer à le traiter afin que la solution ne soit pas appropriée pour les fichiers très volumineux.

Stéphane Chazelas
la source
7

Essayez ceci, si vous en avez gawkou mawkà votre disposition:

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

Cela suppose qu'il n'y a pas d'autre '''-s dans le fichier.

Explication: Il définit le séparateur d'enregistrement sur trois guillemets simples et s'imprime si le numéro d'enregistrement est pair.

Malheureusement, cela ne fonctionnera pas avec toutes les awkimplémentations, car les séparateurs d'enregistrement à plusieurs caractères ne font pas partie de POSIX awk.

joepd
la source
(mon) Le terminal Mac ne connaît pas gawk par défaut.
Emerson Cod
4

Pas aussi agréable que la réponse awk mais comme vous utilisiez à l'origine sed

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

Ou plus court comme l'a souligné Glenn Jackman dans les commentaires (légèrement modifié)

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

Courir comme

sed -f script file

Production

    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
la source
1
Vous pouvez condenser ce sed à sed -n "/'''/,//{//!p}"- probablement faire d' set +Habord en bash pour désactiver l'expansion de l'histoire.
glenn jackman
@glennjackman C'est la raison pour laquelle je l'ai inclus dans un script, l'OMI est toujours plus lisible et à l'abri des fonctions shell telles que la globalisation, l'expansion, etc. Quoi qu'il en soit, je l'ai ajouté à ma réponse car il est plus concis que mon script d'origine.
123