4

I want to do a regex find & replace on a file on the command line with complicated regex, so I need PCRE's & am using perl -pe "s/foo/bar" (rather than sed), that prints out all lines after applying the s///, but it also prints lines that don't match.

Is there a perl command line one-liner which will not print lines that don't match? I know of perl -pe s/foo/bar/ if /foo/, but then I need to duplicate the regex. Is it possible without repeating myself?

Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47
Amandasaurus
  • 58,203
  • 71
  • 188
  • 248

2 Answers2

8

You can use -n flag (which, unlike -p, does not automatically print all lines) and print only lines which match the regex:

perl -ne 's/foo/bar/ && print'

Or, equivalently:

perl -ne 'print if s/foo/bar/'
Dada
  • 6,313
  • 7
  • 24
  • 43
3

The answer from @Dada shows the most concise method to solve the OP's exact problem.
Below are a few other equivalent, but longer, methods to do the same. Their advantage is that these one-liners can be more easily expanded to execute some other additional code (if needed) in addition to simply printing the lines.

perl -ne 'if ( s{foo}{bar} ) { print; }'
# Same:
perl -ne 'next LINE unless s{foo}{bar}; print;'

These can be expanded to:

perl -ne 'if ( s{foo}{bar} ) { some(); other(); code(); print; }'
# Same:
perl -ne 'next LINE unless s{foo}{bar}; some(); other(); code(); print;'

SEE ALSO:

perlrun: command line switches
What should every Perl hacker know about perl -ne?

To see these command line switches in a variety of use cases, including some great Perl one-liners, see:
What is your latest useful Perl one-liner (or a pipe involving Perl)?

Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47