Perl命令适用于命令行,但不适用于bash脚本

问题描述 投票:0回答:1

在更大的bash脚本中,我使用带有perl命令的行来替换文本文件中的时间戳和当前日期和时间。我用以下几行:

perlcmd="perl -i -pe 's/2005-03-31T19:13:30/$(date +"%Y-%m-%dT%H:%M:%S")/' ./file.txt"
echo $perlcmd
$perlcmd

echo命令告诉我perl命令没问题,它的输出是:

perl -i -pe 's/2005-03-31T19:13:30/2017-12-21T11:33:44/' ./file.txt

但是,时间戳不能代替。当我将回显的行粘贴到命令行时,它会正确执行并替换时间戳。如何更改bash脚本中的代码以使其工作?

bash perl substitution
1个回答
0
投票

因为prelcmd变量中的单引号是字面解释而不是语法解释(因为shell命令行处理不是特定于bash但posix shell引用是在参数扩展之前),最简单的是使用数组:

perlcmd=(perl -i -pe 's/2005-03-31T19:13:30/'"$(date +"%Y-%m-%dT%H:%M:%S")"'/' ./file.txt)
echo "${perlcmd[*]}"
"${perlcmd[@]}"

另一个解决方案是使用eval重新解释perlcmd

perlcmd="perl -i -pe 's/2005-03-31T19:13:30/$(date +"%Y-%m-%dT%H:%M:%S")/' ./file.txt"
echo "$perlcmd"
eval "$perlcmd"

以下评论:如果$NewTitle可能包含任何字符,包括/,perl代码将中断或代码可以注入。为了避免这个问题,数据可以通过参数或环境传递,如果数据可以用于正则表达式模式并且可以包含元字符,则可以引用\Q .. \E

按参数:

perl -i -pe 'BEGIN{$old=shift@ARGV;$new=shift@ARGV}s/\Q$old\E/$new/' "$old_title" "$new_title" ./file.txt

按环境:

old_title=$old_title new_title=$new_title perl -i -pe 's/\Q$ENV{old_title}\E/$ENV{new_title}/' ./file.txt
© www.soinside.com 2019 - 2024. All rights reserved.