0

I am trying to replace all digits sequences followed by a line feed and the letter a. Those digits sequences are located in a file called test.txt. The bash script command.sh is used to perform the task (see below).

test.txt

00
a1
b2
a

command.sh

#!/bin/bash

MY_VAR="\d+
a"

grep -P "^.+$" test.txt | perl -pe "s/$MY_VAR/D/";

When I call the command.sh file, here is what I see:

$ ./command
00
a1
b2
a

However, I'm expecting this output:

$ ./command
D1
bD

What am I missing?

Stephan
  • 41,764
  • 65
  • 238
  • 329
  • http://stackoverflow.com/questions/3321829/how-do-i-best-pass-arguments-to-a-perl-one-liner – Hunter McMillen Jul 28 '16 at 17:25
  • `man perlrun` shows that `-p` will cause `perl` to run your command for each line. You can necessarily not replace multiline patterns in a single line. Try to get this working purely with `perl` first, and get to the `bash` part later – that other guy Jul 28 '16 at 17:27
  • Possible duplicate [How to replace multiple any-character (including newline) in Perl RegEx?](http://stackoverflow.com/q/36533282/2173773) – Håkon Hægland Jul 28 '16 at 17:31

1 Answers1

1

You don't even need grep since it is just matching .+, just use perl with -0777 option (slurp mode) to match across the lines:

#!/bin/bash

MY_VAR="\d+
a"

perl -0777pe "s/$MY_VAR/D/g" test.txt

Output:

D1
bD
ikegami
  • 367,544
  • 15
  • 269
  • 518
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 1
    Technically, `-0777` is slurp mode (`-0` splits on null bytes). It makes no difference in this case, but it could in other (admittedly rare) scenarios. – ThisSuitIsBlackNot Jul 28 '16 at 17:55
  • Yes indeed `-0` splits file by null – anubhava Jul 28 '16 at 17:57
  • 1
    The non use of `grep` is a great hint. However, it introduces a new problem resumed in a new question. Would you mind see it? http://stackoverflow.com/q/38656531/363573 – Stephan Jul 29 '16 at 10:34
  • note: bash is not passing variable to perl but generates perl command with newline, injection may be done if variable contains `/` (regex delimiter), safier solution is to pass by evironment or by argument – Nahuel Fouilleul Oct 23 '17 at 10:00