azv
azv

Reputation: 1593

Passing a parameter to perl with -p

I have a short perl script that runs regex replace over files: perl -pi -e 's/x/y/' <file> I want to pass a parameter to the script, so it'll replace y with the command line argument (eg, something like perl -pi -e 's/x/$argv[1]/' <file> but I using $argv[1] doesn't work when the -pi parameter is used.

Upvotes: 0

Views: 384

Answers (3)

ikegami
ikegami

Reputation: 385590

Solution 1: Roll out your own loop.

perl -i -e'$r = shift; while (<>) { s/x/$r/; print }' "$replacement" "$file"

Solution 2: Grab the var at compile time.

perl -i -pe'BEGIN { $r = shift; } s/x/$r/' "$replacement" "$file"

Solution 3: Use an env var instead of an argument

R="$replacement" perl -i -pe's/x/$ENV{R}/' "$file"

Upvotes: 3

Hunter McMillen
Hunter McMillen

Reputation: 61512

perl -pi -e 's/x/y/' <file> is equivalent to this:

while (<>) {
   s/x/y/;
} 
continue {
   print or die "-p failed: $!\n";
}

This will pass every line of <file> through the expression s/x/y/; and print the result. (Note the -i flag will modify <file> inplace). If you really need to pass in a replacement, why don't you list it directly in the substitution. Either way it is still listed only once.

perl -pi -e 's/x/<replacement>/;' <file>

Upvotes: 0

Borodin
Borodin

Reputation: 126722

I have never understood the preoccupation with one-line Perl programs, and I don't understand why you can't write a Perl script file to do this.

However, you can remove an item from @ARGV and save it in a variable before the -p loop starts. Like this

perl -p -i -e 'BEGIN{ $r = pop } s/x/$r/' <file> <replacement>

Upvotes: 5

Related Questions