3

I am trying to use perl's handy non-greedy search pattern but I am having zero luck getting perl to search and replace on specified lines like:

perl -pi -e '10,19s/pat1/pat2/g' file

which I do often using sed. Is there a way to achieve this using perl? I'm in a jam where sed's non-greedy cannot do what I need but perl's will.

jaypal singh
  • 74,723
  • 23
  • 102
  • 147
scriptz
  • 515
  • 2
  • 10

1 Answers1

3

Use the $. variable to match against line numbers.

If you want to replace that pattern between those two line numbers (inclusive), you can use the Range operator .. as demonstrated below:

perl -i -pe 's/pat1/pat2/g if 10 .. 19' file
jaypal singh
  • 74,723
  • 23
  • 102
  • 147
Miller
  • 34,962
  • 4
  • 39
  • 60
  • I wonder if there is a way to exit after the 19th line incases when the file is huge without clobbering the original file. – jaypal singh Aug 13 '14 at 22:01
  • @jaypal See http://stackoverflow.com/questions/25266058/exit-after-extracting-matched-lines-from-log-tail (nevermind, that doesn't work for in-place edits) – ThisSuitIsBlackNot Aug 13 '14 at 22:03
  • @jaypal Not without truncating the file. – Miller Aug 13 '14 at 22:08
  • Miller, Thanks, yeah thats what I thought. @ThisSuitIsBlackNot Thanks for the reference, I was thinking more along the lines of updating the existing file and then quitting after desired lines are edited instead of traversing the entire file skipping the rest of the lines since they were out of range. – jaypal singh Aug 13 '14 at 22:24
  • 3
    @jaypal, Of course not; you still have to write the rest of the output file, which requires reading the rest of the input file. At best, you can stop checking the regex. `perl -i -e'while (1) { exit unless $_ = <>; s/pat1/pat2/g; print; last if $. == 19; } print while <>;' file` – ikegami Aug 13 '14 at 22:52
  • Aah thats clever. I did a small test on 100,000,000 lines (basically numbers). Shaved off 20% on execution time. Thanks @ikegami appreciate your help and guidance as always. – jaypal singh Aug 13 '14 at 23:01