在这个perl oneliner中,如何在系统命令中转义双引号?

时间:2019-03-27 23:28:23

标签: bash perl syntax quoting

出于启发,我想了解如何在以下perl oneliner中的system命令中转义引号:

$ ls -p | grep -v / | perl -lane 'system("echo \"$_\"");'

不使用\"转义序列,而按此处显示的方式:https://stackoverflow.com/a/1250279/3367247

(显然,该命令没有任何用处;它只打印文件名中带有空格的文件名。但是它可以用来简洁地解释我的问题。)

我尝试了以下操作(请原谅图像,但是我发现突出显示最容易破译报价):

  1. 带双引号的系统命令:system("echo "$_"") enter image description here

代码:$ ls -p | grep -v / | perl -lane 'system("echo ''"''$_''"''");'

  1. 单引号的系统命令:system('echo "$_"') enter image description here

代码:$ ls -p | grep -v / | perl -lane 'system('"'"'echo "$_"'"'"');'

这些都不起作用。有没有办法以链接答案的方式来完成此任务?

编辑:我需要在echo命令中的$_周围加上双引号,因为$_中的字符串包含括号,而不是因为它包含空格,就像我最初认为的那样

2 个答案:

答案 0 :(得分:1)

我想发表一些我从有益的评论和接受的答案中收集到的见解(谢谢大家!)。在原始命令中,我提出了: $ ls -p | grep -v / | perl -lane 'system("echo \"$_\"");'两个解释器:bash和perl发挥作用:

  1. 由bash解释的原始命令不会触及(一对)单引号内的任何内容(即-lane之后的所有内容),并将其完整地作为脚本传递给perl。 / p>

  2. 然后,perl解释器将处理此脚本,该脚本由单个system命令组成。 perl 解释器负责生成最终的echo命令行,然后将其返回bash进行解释。这最后一个bash命令需要从$_动态生成。有两种方法可以做到这一点:

    (a)使用带双引号的系统命令,以便对$_进行内插[即system("echo $_")]但是请注意,回显的字符串周围必须有",因为它可能包含括号。因此,我们需要 perl 在此最后的 bash 命令字符串中,在"周围发出文字$_ s(这将通过扩展被发送到bash之前的"个外部)。现在有两种方法可以完成 this

    (a-i)使用"转义\来产生文字引号:"echo \"$_\""

    (a-ii)使用qq运算符,该运算符会降级perl字符串中与"一致的特殊状态,然后可以将其用作普通字符:qq(echo "$_")

    (b)-或-生成最终bash命令的另一种方法是在system命令中使用引号,如@Håkon在其答案中所建议的:{{1 }}。但是我们仍然需要如前所述在system('echo ' . $_)周围加上引号,因此我们需要将其更改为:$_。现在,任务简化为找出bash的单引号转义符,以确保perl可以看到此字符串。

perl命令的最终形式为:

2-a-i:system('echo "' . $_ . '"')

2-a-ii:perl -lane 'system("echo \"$_\"");'

最后:

2-b:perl -lane 'system(qq/echo "$_"/);'

我打算实现perl -lane 'system('"'"'echo "'"'"'.$_.'"'"'"'"'"');'' s的这种变态,因此实现了任务! :D

编辑注释:从实用的可用性角度来看,"形式似乎最适合将最终的所需bash命令粘贴到perl qq调用中(然后您可以将文件名替换为system

答案 1 :(得分:0)

  

我想了解如何在系统命令中对引号进行转义   以下perl oneliner:

$ ls -p | grep -v / | perl -lane 'system("echo \"$_\"");'
     

不使用\“转义序列,按照下面显示的方式:[...]

这些示例用于转义引号,您的示例使用 double 引号\"$_\"。在Bash中,单引号内的所有内容均按字面意义使用(单引号本身除外),双引号内的内容并非如此。例如,双引号内的$不是文字$,而是表示要跟随变量扩展。

现在,在您的命令中,报价解释分为三个级别。

  • 首先是外壳(命令行):

    perl -lane 'system("echo \"$_\"");'
    
  • 然后是perl解释器:

    system("echo \"$_\");
    
  • 然后是第二个外壳(这里使用Bash):

    echo "xxx"
    

其中xxx$_脚本中perl的扩展

您的命令不包含任何内部引号,因此无需使用Bash引号结构来转义单引号,例如

It's fine  -> 'It'"'"'s fine'

It's fine  -> 'It'\''s fine'

此外,您需要在perl脚本中转​​义双引号

system("echo \"$_\"")

由于它们在双引号内,或者您可以将其删除 因为echo在这里不需要双引号:

system("echo $_")

可以很好地工作,或者您可以按照注释中的建议进行操作:

system(qq/echo "$_"/)

或使用LIST form of system with more than one argument

system("/bin/echo", $_)

但是,如果要使用单引号,例如:

system('echo ' . $_)

您将需要调用shell的单引号转义符:

'system('"'"'echo ''"' . $_)'

或(使用双引号):

"system('echo ' . "'$'"_)"