28

I basically want to do this:

cat file | grep '<expression>' | sed 's/<expression>/<replacement>/g'

without having to write the expression twice:

cat file | sed 's/<expression>/<replacement>/g'

Is there a way to tell sed not to print lines that does not match the regular expression in the substitute command?

Ropez
  • 3,485
  • 3
  • 28
  • 30
  • 2
    Use the -n option (as in `sed -n`) to suppress the output and use p option (next to your g as in `/g;p` to print only those lines where changes takes place. – jaypal singh Nov 22 '11 at 15:38
  • Hi Ropez, I have placed the response in the answer section for better formatting. – jaypal singh Nov 24 '11 at 10:33

4 Answers4

34

Say you have a file which contains text you want to substitute.

$ cat new.text 
A
B

If you want to change A to a then ideally we do the following -

$ sed 's/A/a/' new.text 
a
B

But if you don't wish to get lines that are not affected with the substitution then you can use the combination of n and p like follows -

$ sed -n 's/A/a/p' new.text 
a
Community
  • 1
  • 1
jaypal singh
  • 74,723
  • 23
  • 102
  • 147
18

This might work for you:

sed '/<expression>/!d;s//<replacement>/g' file

Or

sed 's/<expression>/<replacement>/gp;d' file
potong
  • 55,640
  • 6
  • 51
  • 83
  • "cat file" was just an example, in the actual use case, the input came from a git command. – Ropez Nov 23 '11 at 07:25
4
cat file | sed -n '/<expression>/{s//<replacement>/g;p;}'
mitchnull
  • 6,161
  • 2
  • 31
  • 23
  • 1
    +1, but note that "...g;p;}" is non-standard and will not work in all sed. Also, UUOC. – William Pursell Nov 22 '11 at 11:17
  • @WilliamPursell Care to elaborate which part of that is non-standard? `...g;p}` would only work on gnu sed, but the way I put in my answer is standard, to the best of my knowledge. – mitchnull Nov 22 '11 at 13:58
  • Some versions of sed do not allow ';' to delimit commands, but require an actual carriage return. Those versions of sed are very annoying to use ;) – William Pursell Nov 22 '11 at 14:16
  • @WilliamPursell Well, according to the [spec](http://pubs.opengroup.org/onlinepubs/007904875/utilities/sed.html), separating commands with `;` is standard: `Command verbs other than {, a, b, c, i, r, t, w, :, and # can be followed by a semicolon, optional s, and another command verb. However, when the s command verb is used with the w flag, following it with another command in this manner produces undefined results.`, so those "other" sed implementations are broken :) – mitchnull Nov 23 '11 at 07:58
-3

How about:

cat file | sed 'd/<expression>/'

Will delete matching patterns from the input. Of course, this is opposite of what you want, but maybe you can make an opposite regular expression?

Please not that I'm not completely sure of the syntax, only used it a couple of times some time ago.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621