Extrair texto entre três aspas simples

8

Eu tenho o seguinte em um arquivo

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

com várias outras coisas neste arquivo.

Extrato essa parte no meu script de shell via sed -n "/'''/,/'''/p" $1(onde $1está o arquivo).

Isso me dá uma variável com o conteúdo como um 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. '''

Como posso agora extrair a parte entre o '''?

Ou existe ainda uma maneira melhor de recuperá-lo do arquivo de múltiplas linhas?

Estou no Mac El Captain 10.11.2 e GNU bash, versão 3.2.57 (1) -release (x86_64-apple-darwin15)

Emerson Cod
fonte
3
Coloque aspas duplas em torno da variável, pois ela contém novas linhas.
DisplayName
1
Este é YAML, certo? Algum motivo para você não estar realmente usando um analisador YAML?
Charles Duffy
@DisplayName, ... para ser claro, você quer dizer aspas duplas ao ecoar , certo?
Charles Duffy

Respostas:

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

extrairia (e imprimiria seguido por uma nova linha) a parte entre cada par de '' '.

Cuidado que perlretira o arquivo inteiro da memória antes de iniciar o processamento, para que a solução não seja apropriada para arquivos muito grandes.

Stéphane Chazelas
fonte
7

Tente isto, se você tiver gawkou estiver mawkà sua disposição:

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

Isso pressupõe que não há outros '''-s no arquivo.

Explicação: Define o separador de registros para três aspas simples e é impresso se o número do registro for par.

Infelizmente, ele não funcionará com todas as awkimplementações, pois os Separadores de Registros com vários caracteres não fazem parte POSIX awk.

joepd
fonte
(my) O terminal Mac não sabe gawk por padrão.
Emerson Cod
4

Não é tão bom quanto a resposta awk, mas como você estava usando originalmente o sed

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

Ou mais curto, como apontado por Glenn Jackman nos comentários (ligeiramente alterado)

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

Correr como

sed -f script file

Resultado

    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
fonte
1
Você pode condensar isso sed -n "/'''/,//{//!p}"- provavelmente terá que fazer set +Hprimeiro no bash para desativar a expansão do histórico.
Glenn Jackman
@glennjackman Essa foi a razão pela qual eu o incluí em um script, a IMO é sempre mais legível e imune a funções de shell, como globbing, expansão etc.
123