Makodia
Makodia

Reputation: 1

How to replace text in a existing file using script on linux?

I want to replace abc with XYZ, for which have written below script in a file named test.sh; the file is executed on terminal with sh test.sh command

i='abc';

Command:

perl -pi -e 's/$i/XZY/g' /home/user/Desktop/file.txt

gedit file.txt

But the output is:

XYZaXYZbXYZc
XYZ

Can't able to figure out the problem.

Upvotes: 0

Views: 195

Answers (4)

SethB
SethB

Reputation: 2090

I believe you need to use double quotes(") instead of single quotes('). Single quotes are used for literal strings.

perl -pi -e "s/$i/XZY/g" /home/user/Desktop/file.txt

http://www.perlmonks.org/?node_id=401006

To match a / you have to escape it. \/. The new problem is that you have to escape the \ when you are building you original string.

i="a\\/b";
perl -pi -e "s/$i/XZY/g" /home/user/Desktop/file.txt

Upvotes: 0

ikegami
ikegami

Reputation: 386646

Characters in single quotes are passed to the program without processing. You're passing the two characters $i to Perl, not the value of the shell variable $i, so Perl uses the value of its (empty) variable $i.


If $i contains text (a*c should match a*c), this is the most flexible in what $i is allowed to contain:

perl -i -pe'BEGIN { $text=shift(@ARGV) } s/\Q$text/XZY/g' "$i" file

or

TEXT="$i" perl -i -pe's/\Q$ENV{TEXT}/XZY/g' file

If $i contains a regex pattern (a*c should match a*cccc), then you want:

perl -i -pe'BEGIN { $re=shift(@ARGV) } s/$re/XZY/g' "$i" file

or

RE="$i" perl -i -pe's/$ENV{RE}/XZY/g' file

Upvotes: 1

Mark
Mark

Reputation: 2822

The problem is

's/$i/XZY/g' 

The use of single quotes here keeps variable interpolation from happening, so $i is passed as a literal to the Perl interpreter. Since you haven't defined $i in your Perl one-liner, the regular expression becomes

s//XYZ/g

or in other words, insert 'XYZ' after each character in the file.

The solution is to use double-quotes instead.

Upvotes: 1

devnull
devnull

Reputation: 123648

The problem is that you are using single quotes which prevent variable expansion. So the command you executed is essentially equivalent to saying:

perl -pi -e 's//XZY/g' /home/user/Desktop/file.txt

which performs the substitution for every character including newlines.

Use double quotes:

perl -pi -e "s/$i/XZY/g" /home/user/Desktop/file.txt

Upvotes: 1

Related Questions