Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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)

share|improve this question
3  
Put double quotes around the variable, it contains newlines then. – DisplayName Jan 11 at 13:39
1  
This is YAML, right? Any reason you aren't actually using a YAML parser? – Charles Duffy Jan 11 at 16:24
    
@DisplayName, ...to be clear, you mean double quotes when echoing, right? – Charles Duffy Jan 11 at 16:26
up vote 12 down vote accepted
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.

share|improve this answer
    
thanks - that worked :) – Emerson Cod Jan 11 at 14:49

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.

share|improve this answer
    
(my) Mac terminal does not know gawk per default. – Emerson Cod Jan 11 at 14:51

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.
share|improve this answer
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 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 at 12:00

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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