8

I have the following in a file

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

with several other things in this file.

I extract this part in my shell script via sed -n "/'''/,/'''/p" $1 (where $1 is the file).

This gives me a variable with the content as one 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. '''

How can I now extract the part between the ''' ?

Or is there even a better way to retrieve it from the multiline file ?

I'm on Mac El Captain 10.11.2 and GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)

  • 3
    Put double quotes around the variable, it contains newlines then. – DisplayName Jan 11 '16 at 13:39
  • 1
    This is YAML, right? Any reason you aren't actually using a YAML parser? – Charles Duffy Jan 11 '16 at 16:24
  • @DisplayName, ...to be clear, you mean double quotes when echoing, right? – Charles Duffy Jan 11 '16 at 16:26
12
perl -l -0777 -ne "print for /'''(.*?)'''/gs" file

would extract (and print followed by a newline) the part between each pair of '''.

Beware that perl slurps the whole file in memory before starting processing it so that solution may not be appropriate for very large files.

7

Try this, if you have gawk or mawk to your disposal:

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

This assumes that there are no other '''-s in the file.

Explanation: It sets the record separator to three single quotes, and prints if the record number is even.

Unfortunately, it won't work with all awk implementations, as multi-character Record Separators are not part of POSIX awk.

  • (my) Mac terminal does not know gawk per default. – Emerson Cod Jan 11 '16 at 14:51
4

Not as nice as the awk answer but as you were originally using sed

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

Or shorter as pointed out by glenn jackman in the comments (slightly changed)

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

Run as

sed -f script file

Output

    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.
  • 1
    You can condense that sed to sed -n "/'''/,//{//!p}" -- probably have to do set +H first in bash to turn off history expansion. – glenn jackman Jan 11 '16 at 22:15
  • @glennjackman That was the reason i have included it in a script, IMO it's always more readable and as is immune to shell functions such as globbing,expansion etc. Anyway i added it to my answer as it is more concise than my original script. – 123 Jan 12 '16 at 12:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.