Zombo
Zombo

Reputation: 1

sed emulate "tr | grep"

Given the following file

$ cat a.txt
FOO='hhh';BAR='eee';BAZ='ooo'

I can easily parse out one item with tr and grep

$ tr ';' '\n' < a.txt | grep BAR
BAR='eee'

However if I try this using sed it just prints everything

$ sed 's/;/\n/g; /BAR/!d' a.txt
FOO='hhh'
BAR='eee'
BAZ='ooo'

Upvotes: 3

Views: 1088

Answers (5)

Zombo
Zombo

Reputation: 1

$ sed 's/;/\n/g;/^BAR/!D;P;d' a.txt
BAR='eee'
  • replace all ; with \n
  • delete until BAR line is at the top
  • print BAR line
  • delete pattern space

Upvotes: 0

jitendra
jitendra

Reputation: 1458

The following grep solution might work for you:

grep -o 'BAR=[^;]*' a.txt

Upvotes: 0

Rubens
Rubens

Reputation: 14778

sed can do it just as you want:

sed -n 's/.*\(BAR[^;]*\).*/\1/gp' <<< "FOO='hhh';BAR='eee';BAZ='ooo'"

The point here is that you must suppress sed's default output -- the whole line --, and print only the substitutions you want to performed.

Noteworthy points:

  • sed -n suppresses the default output;
  • s/.../.../g operates in the entire line, even if already matched -- greedy;
  • s/.1./.2./p prints out the substituted part (.2.);
  • the tr part is given as the delimiter in the expression \(BAR[^;]*\);
  • the grep job is represented by the matching of the line itself.

Upvotes: 2

Scrutinizer
Scrutinizer

Reputation: 9936

With awk you could do this:

awk '/BAR/' RS=\; file

But if in the case of BAZ this would produce an extra newline, because the is no ; after the last word. If you want to remove that newline as well you would need to do something like:

awk '/BAZ/{sub(/\n/,x); print}' RS=\;  file

or with GNU awk or mawk you could use:

awk '/BAZ/' RS='[;\n]'

If your grep has the -o option then you could also try this:

grep -o '[^;]*BAZ[^;]*' file

Upvotes: 2

John Zwinck
John Zwinck

Reputation: 249424

awk 'BEGIN {RS=";"} /BAR/' a.txt

Upvotes: 1

Related Questions