How to pass a path to a file through a call to perl from bash?

je_b

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

 directory=`pwd`
 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.

terdon

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章