我试图在Perl单线程中打印单引号时遇到了这个问题。我最终发现你必须用'\''
逃脱它们。这里有一些代码来说明我的问题。
让我们从打印文本文件开始。
perl -ne 'chomp; print "$_\n"' shortlist.txt
red
orange
yellow
green
blue
现在让我们为每一行打印文件的名称。
perl -ne 'chomp; print "$ARGV\n"' shortlist.txt
shortlist.txt
shortlist.txt
shortlist.txt
shortlist.txt
shortlist.txt
然后我们可以在每一行周围添加单引号。
perl -ne 'chomp; print "'$_'\n"' shortlist.txt
shortlist.txt
shortlist.txt
shortlist.txt
shortlist.txt
shortlist.txt
等等没有用。我们再试一次。
perl -ne 'chomp; print "'\''$_'\''\n"' shortlist.txt
'red'
'orange'
'yellow'
'green'
'blue'
所以我现在就开始工作了。但我仍然对为什么'$ _'评估程序名称感到困惑。也许这很容易,但是有人可以解释或链接到某些文档吗?
编辑:我在Red Hat 5上运行Perl 5.8.8
答案 0 :(得分:12)
您在单行中使用单引号来保护您的Perl代码不被shell评估。在此命令中:
perl -ne 'chomp; print "'$_'\n"' shortlist.txt
您在$_
之前关闭单引号,因此shell会将$_
展开为the last argument to the previous command。在您的情况下,这恰好是输入文件的名称,但如果您先运行不同的命令,输出会有所不同:
$ echo foo
$ perl -ne 'chomp; print "'$_'\n"' shortlist.txt
foo
foo
foo
foo
foo
答案 1 :(得分:11)
对于你的shell,'chomp; print "'$_'\n"'
会产生一个串联的字符串
chomp; print "
(单引号内的第一个序列),$_
和\n"
(单引号内的第二个序列)。在bash
中,$_
“扩展到上一个命令的最后一个参数,扩展后......”。由于这恰好是shortlist.txt
,因此以下内容传递给perl
:
chomp; print "shortlist.txt\n"
例如,
$ echo foo
foo
$ echo 'chomp; print "'$_'\n"'
chomp; print "foo\n"
答案 2 :(得分:5)
出于这个原因,我尽量避免在一个衬里中引用。我可以使用广义引用:
% perl -ne 'chomp; print qq($_\n)'
虽然我可以避免使用-l
开关来免费获取换行符:
% perl -nle 'chomp; print $_'
如果我不理解单行,我使用-MO=Deparse
来看看Perl认为它是什么。前两个是你所期望的:
% perl -MO=Deparse -ne 'chomp; print "$_\n"' shortlist.txt
LINE: while (defined($_ = <ARGV>)) {
chomp $_;
print "$_\n";
}
-e syntax OK
% perl -MO=Deparse -ne 'chomp; print "$ARGV\n"' shortlist.txt
LINE: while (defined($_ = <ARGV>)) {
chomp $_;
print "$ARGV\n";
}
-e syntax OK
你在看到问题的那个地方看到了一些有趣的东西。变量在perl
看到它之前消失了,并且它的位置有一个常量字符串:
% perl -MO=Deparse -ne 'chomp; print "'$_'\n"' shortlist.txt
LINE: while (defined($_ = <ARGV>)) {
chomp $_;
print "shortlist.txt\n";
}
-e syntax OK
您的修补程序也很奇怪,因为Deparse将变量名称放在大括号中以将其与旧的包装说明符'
分开:
% perl -MO=Deparse -ne 'chomp; print "'\''$_'\''\n"' shortlist.txt
LINE: while (defined($_ = <ARGV>)) {
chomp $_;
print "'${_}'\n";
}
-e syntax OK