2

I want to replace the string using a shell variable.

today =`date '+%Y%m%d'`

perl -p -i -e 's/file"20221212"/file="${today}"/g' 

The expectation is file="20221215". But it failed, result is file="".

How to escape this case?

pmqs
  • 3,066
  • 2
  • 13
  • 22
92rwf0lXXW4m
  • 115
  • 1
  • 7
  • This is a duplicate of [How can I process options using Perl in -n or -p mode?](https://stackoverflow.com/q/53524699/589924) – ikegami Dec 15 '22 at 22:06

3 Answers3

5

Your issue is shell quoting. Using single quotes, ', to delimit the Perl code disables all variable expansion. You need to use double quotes, ", to get variable expansion.

Using shell without any Perl to illustrate the issue

today=`date '+%Y%m%d'`
echo 'today is $today'

will output this -- with no expansion of $today

today is $today

now with double quotes

today=`date '+%Y%m%d'`
echo "today is $today"

outputs this -- $today has been expanded.

today is 20221215

Applying that to your code (I've removed the -i option to make it easier to see the results) and escaped all double quotes in the perl code with \"

echo 'file"20221212"' >input.txt
perl -p  -e "s/file\"20221212\"/file=\"${today}\"/g" input.txt 

gives

file="20221215"
pmqs
  • 3,066
  • 2
  • 13
  • 22
  • 1
    I like to tell people that the -e argument is just a string. Whatever your shell does to make that string and pass it on is what you have to do. – brian d foy Dec 15 '22 at 19:10
2

Here I am giving you the hint how it should be:

I cannot reproduce the issue from your code.

#!/bin/sh
today=`date '+%Y%m%d'`
echo "today:$today"

file="input.txt";

perl -pi -e 's/file20221212/file='${today}'/g' $file

where input.txt contains:

file20221212
vkk05
  • 3,137
  • 11
  • 25
1

The two earlier answers are horrible. Don't generate Perl code from the shell.

This question was already asked and answered here: How can I process options using Perl in -n or -p mode?

It provides three solution, including

perl -spe's/file\K"20221212"/="$today"/g' -- -today="$today"
TODAY="$today" perl -pe's/file\K"20221212"/="$ENV{today}"/g' 

Alternatively, you could also avoid date and passing a value entirely.

perl -MPOSIX -pe'
   BEGIN { $today = strftime "%Y%m%d", localtime }
   s/file\K"20221212"/="$today"/g
' 
ikegami
  • 367,544
  • 15
  • 269
  • 518