繁体   English   中英

如何使用Perl替换运算符禁用变量插值?

[英]How can I disable variable interpolation with the Perl substitution operator?

我正在尝试替换VMS上的文本文件中的特定行。 通常,这是一个简单的Perl单线程。 但是当替换方是包含VMS路径的符号时,我遇到了问题。 这是文件和我尝试的内容:

file1.txt的内容:

foo
bar
baz
quux

尝试替换第3行:

$ mysub = "disk$data1:[path.to]file.txt"
$ perl -pe "s/baz/''mysub'/" file1.txt

产生以下输出:

foo
bar
disk:[path.to]file.txt
quux

看起来Perl过于苛刻,用一个不存在的变量的内容替换路径的$data1部分(即什么都没有)。 运行调试器确认了这一点。 我没有提供/e ,所以我认为Perl应该直接替换文本。 有没有办法让Perl这样做?

(另请注意,我可以在linux命令行中重现类似的行为。)

正如Ruakh在阅读我的评论时发现的那样,perl插值问题可以通过访问%ENV哈希来解决,而不是使用shell变量:

perl -pwe "s/baz/$ENV{mysub}/" file1.txt

添加-w因为我不相信即使在单行中也不使用warnings

只需正确混合引号和双引号,您就可以到达:

我们创建了“string”+“替换符号”+“string”的紧密连接。 两个双引号字符串包含替换的单引号。 Contrived ......但它确实有效。

$ perl -pe "s'baz'"'mysub'"'" file1.txt

这是一个DCL级别的解决方案。

对于Perl解决方案,使用q()运算符作为非插值字符串并执行它。 使用简单的DCL替换将符号填入parens。 这是我的最爱,因为它(几乎)对我有意义,并且不会引起混淆。

$ perl -pe "s/baz/q(''mysub')/e" file1.txt

几十年来甚至没有见过VMS系统,但是......逃避你的印记?

$ mysub = "disk\$data1:[path.to]file.txt"

或者可能

$ mysub = "disk\\$data1:[path.to]file.txt"

对于sh或衍生物,我会使用

perl -pe'BEGIN { $r = shift(@ARGV) } s/baz/$r/' "$mysub" file1.txt

否则,你必须以某种方式将mysub的值转换为Perl字符串文字。 那会更复杂。 找到你的shell的等价物。

由OP编辑:

是的,这很有效。 VMS等价物是

perl -pe "BEGIN { $r = shift(@ARGV) } s/baz/$r/" 'mysub' file1.txt

使用sed。

Sed不会尝试将$data1插入为变量,因此您应该得到您想要的。

$ sed -e "s/baz/''mysub'/" file1.txt

你必须逃离$\\$ 否则,Perl中看到一个变量引用,并替换字符串$data1与内容$data1正则表达式求值之前。 由于你没有定义$data1它当然是空的。

您可以使用以下代码:

$ mysub='disk\$data1:[path.to]file.txt'
$ perl -pe 's/baz/'$mysub'/' FILE
foo
bar
disk$data1:[path.to]file.txt
quux

您可以尝试使用逻辑名称而不是DCL符号:

$ define mysub "disk$data1:[path.to]file.txt"
$ $ perl -pe "s/baz/mysub/" file1.txt

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM