This is a more advanced version of a previous question (How to pass arguments to perl when trying to change a line?) I made.

This time I am trying to pass a path, but evertything seems that the the perl script is readin the / wrongly.

Suppose the line 4 in file.txt looks like this

 path_root_abs = "/path/to/thefile"

To obtain the working directory and replace it in /path/to/file I did

 perl -i -pe "s/(path_root_abs\s=\s\")(.*)(\")/\$1${directory}$3/ if \$. == 4" file.txt

And got:

Bareword found where operator expected at -e line 1, near "s/(path_root_abs\s=\s")(.*)(")/$1/scratch"
syntax error at -e line 1, near "s/(path_root_abs\s=\s")(.*)(")/$1/scratch"
Execution of -e aborted due to compilation errors.

What should I do to avoid unix reading the \ that comes after scratch as a bareword.

  • If I add a \ before ${directory} the file.txt is changed to path_root_abs = "" – je_b Mar 10 '15 at 23:25
  • Note that, if you might have more than one space, or no space, before or after the =, you should use \s*. (And you need to use \s rather than a plain space if the file might have tabs in it.) – Scott Mar 10 '15 at 23:54

The first issue is that $directory contains slashes which are also being used as the delimiter for the substitution operator (s///). Basically, if $directory is /home/je_b, what Perl sees is:

 perl -i -pe "s/foo//home/jb/ if \$. == 4" file.txt

It takes the / of /home as the second / of the s/// operator. The simplest solution is to use a different character instead of /:

perl -i -pe "s#foo#${directory}#" file.txt

You can also simplify in other ways though. Consider this:

perl -pe "s#(path_root_abs = \")(.*)#\1${directory}\"# if \$. == 4" file
  • There's no need for \s when you only need to match one space, just use a space.
  • Perl's substitution operator understands both $1 and \1 so use the latter and avoid escaping.
  • There's no point in capturing the " character. If you know it's there, add it yourself.

Finally, you could also get the pwd from Perl directly. Perl has access to all exported shell variables through the %ENV hash. So, you could just do:

perl -pe 's#(path_root_abs = ").*#$1$ENV{PWD}"# if $.==1' file
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.