one.txt contents as below.

Hi this is the first line in a file one.txt
cooler:some default cooler string `/var/log/cooler_x86_64_someos8.4/config.cf'
doing good nice!
all is well
Hi this is the lastline in a file one.txt

Expected output


I need as below

cat one.txt | grep cooler | sed somergexp


Yes first is back quote and end is single quote


I could able to do with using two sed's as below

sed 's:^.*\(`.*\)'\''.*$:\1:'| sed 's/`//'

but need to do with a single sed call.

  • can u confirm the single quote at the end of second line in one.txt... I suspect it should be a backtick. – Siva Jan 27 '20 at 7:33
  • So you want to extract the path and also change someos to ubanto? – Kusalananda Jan 27 '20 at 11:28

Try this,

grep -o '[^`]*/cooler[^`]*' one.txt
  • -o Print only the matched

i could able to solve the issue with sed 's:[^/]*\(.*\)'\''.*$:\1:'

  • This correctly picks out the pathname from the line where it occurs, but it also prints out all other lines from the given text. It also does weird things with an extra line if it says, for example, Is this good/bad? It's hard to say. – Kusalananda Jan 27 '20 at 12:48
sed -n -r '/^cooler/s|.*['\''`"]([^'\''"`]+).*|\1|gp' one.txt

-n silent
/^cooler/ pattern
gp - output result
.*['\''`"] - character group before quotation marks('`")
([^'\''"`]+) - a group of characters after the quotation mark, except for the following quotation marks('`")


Let's start by picking out the line of interest. That line starts with the string cooler::

$ sed -e '/^cooler:/!d' file
cooler:some default cooler string `/var/log/cooler_x86_64_someos8.4/config.cf'

The expression /^cooler:/!d would delete all lines from the input that does not match /^cooler:/.

Then we extract the thing between a backquote and a quote:

$ sed -e '/^cooler:/!d' -e "s/.*\`\([^']*\)'.*/\1/" file

The expression s/.*\`\([^']*\)'.*/\1/ substitutes the whole line with the string within `...'. The backquote needs to be escaped since this expression is within double quotes (it would be the start of a command substitution in the shell otherwise).

You could also do the extraction of the path in two steps: Remove everything up to and including the backquote, and then remove everything after and including the single quote. This may even look a bit tidier:

$ sed -e '/^cooler:/!d' -e 's/.*`//' -e "s/'.*//" file

Another couple of variations on Regular Expressions

  1. Using sed

    sed -n '/^cooler:/s/^.*`\(.*\)'"'"'/\1/p'

    This can be explained as follows

    • -n don't print anything unless there is a match
    • ^cooler: look for cooler: at the beginning of the line
    • s/old/new/p replace old with new and print result if the substitution succeeded
    • ^.*`\(.*\)'"'"' matches everything to the backtick, then captures everything inside the brackets ( ... ), then captures a singlequote to the end of the line. The '"'"' is shell fluff - the first ' ends the initial single-quoted string, the "'" quotes a single-quote, the final ' restarts a single-quoted string
    • \1 in the replacement part references the captured string from the pattern match
  2. Using GNU grep

    grep -oP '^cooler:.*`\K'"[^']*"

    This can be explained in much the same way as before

    • -oP only print the match, and use perl regular expressions (PCRE) for parsing
    • \K a boundary: everything before this is matched but discarded; everything afterwards is included in the result
    • [^']* matches everything except a single-quote
$ sed -ne '
' one.txt

This is posix sed and we change quote n back quote to newlines. Then the path is Sandwiched between the two newlines.

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.