user5511576 user5511576 - 3 months ago 11
Linux Question

perl -p -i -e replace line with text containing symbol

In a linux Vm, I am trying to change the second line of 50+ files.

I have used this command below successfully for strings without symbols.

perl -p -i -e 's/.*/new_line / if $.==2' .


However now I am trying to add the new string " # $new_line $ " using this command :

perl -p -i -e 's/.*/# $Header$ / if $.==2' .


But getting the following error:

Final $ should be \$ or $name at -e line 1, within string
syntax error at -e line 1, near "s/.*/# $Header$ /"
Execution of -e aborted due to compilation errors.


Any help is appreciated. Thank you in advance.

Answer

The error message tells you exactly what is wrong:

Final $ should be \$ or $name at -e line 1, within string

You need to escape the $s. It is seeing the second $ as part of a variable, but it's not.

You'll also need to escape the first $ because Perl sees $Header as a variable, and will substitute the value of $Header instead of the actual string $Header. Since $Header has no value, you'll just get an empty string.

You also can't specify . as the files to operate on. . is a directory, and Perl will tell you that if you try to use it as a file:

Can't do inplace edit: . is not a regular file.

You also want to use the -l flag to make sure that Perl handles line endings correctly. When you replace the entire string with your new string, you're not including the \n at the end.

So what you want is:

perl -l -p -i -e 's/.*/# \$Header\$ / if $.==2' *.html

(replace *.html with your own filespec)

Finally, you could also just replace the working variable $_ with the string you want, rather than using the s///, like so:

perl -l -p -i -e '$_ = q{# $Header$} if $.==2'  *

q{xyz} is the same as 'xyz', where no interpolation is done.