Filip Stefanov
Filip Stefanov

Reputation: 842

Perl regex expand variable and die if file does not exist

i Found this line:

perl -p -i -e 'BEGIN{ -f $ARGV[0] or die"no file" } s/foo/bar/'
non-existent-file.txt

And i would like to make it work for my case. Expand variables inside the substitution but im not familiar with Perl syntax at all :)

perl -i -0777 -pe 'BEGIN{ -f $ARGV[0] or die".HEAD file is missing" }'
"s|^\\Q${repo}:\\E.+$|${newrepo}|gm" .HEAD;

.HEAD file is missing at -e line 1. BEGIN failed--compilation aborted at -e line 1.

Upvotes: 0

Views: 214

Answers (2)

ikegami
ikegami

Reputation: 385819

Don't (try to) generate Perl code in a shell script!!!

perl -i -pe'
   BEGIN {
      $repo    = shift(@ARGV);
      $newrepo = shift(@ARGV);

      open(my $fh, '<', $ARGV[0])
         or die("Can't open $ARGV[0]: $!\n");
   }
   s|^\Q$repo:\E.+$|$newrepo|g;
' "$repo" "$newrepo" .HEAD

or

export repo
export newrepo
perl -i -pe'
   BEGIN {
      open(my $fh, '<', $ARGV[0])
         or die("Can't open $ARGV[0]: $!\n");
   }
   s|^\Q$ENV{repo}:\E.+$|$ENV{newrepo}|g;
' .HEAD

or

repo="$repo" newrepo="$newrepo" perl -i -pe'
   BEGIN {
      open(my $fh, '<', $ARGV[0])
         or die("Can't open $ARGV[0]: $!\n");
   }
   s|^\Q$ENV{repo}:\E.+$|$ENV{newrepo}|g;
' .HEAD

Notes:

  • The file can exist even if -f returns false. The actual error is in $!. Using open is even more accurate at checking if the file can be opened than -f.

  • I added line breaks added for readability. Remove them if you want, but there's no need to do so.

  • I removed the useless -0777, and the /m that became useless as a result.

Upvotes: 3

choroba
choroba

Reputation: 241888

Perl variables aren't the same as shell variables. To pass values to the script, you can use paramteres, but then you need to stop processing the input on the first eof, otherwise Perl would treat the parameters as filenames, too:

perl -i -0777 -ne 'BEGIN { ($file, $repo, $new) = @ARGV;
                           die "$file missing\n" unless -f $file;
                   }
                   s/^\Q$repo:\E.+$/$new/gm;
                   print;
                   last if eof;
                  ' -- .HEAD "$repo" "$newrepo"

Or, open the file yourself:

if perl -0777 -e '($file, $repo, $new) = @ARGV;
                  open $FH, "<", $file or die "$file: $!";
                  while (<$FH>) {
                      s/^\Q$repo:\E.+$/$new/gm;
                      print;
                  }' -- .HEAD "$repo" "$newrepo" > newfile
then
   mv newfile .HEAD
fi

Upvotes: 3

Related Questions