如何通过命令行将双引号(")或单引号(')读入我的perl程序?

时间:2017-06-08 10:47:47

标签: perl shell

我正在尝试将作为命令行参数传递的use参数用到我的脚本中,但是这样做时双引号(")和单引号(')就会消失。 例如,运行以下内容:

#!usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my $argument_list = join(" ",@ARGV);

print "$argument\n";

运行上面的代码:

perl test1.pl name1 "name2 and name3"

我得到以下输出:

name1 name2 and name3

有没有办法在命令行参数中包含双引号,以便最终参数为"name2 and name3"而不只是name2 and name3

我尝试过使用' \'要转义双引号perl test1.pl name1 \"name2 and name3\",但只会将"name2作为单独的参数and作为单独的参数并将name3"视为另一个参数而使情况更糟。

5 个答案:

答案 0 :(得分:3)

您看到的行为是您正在使用的shell的一个功能,与perl没有任何关系。无论您使用的是Python还是C或其他语言,都会看到相同的结果。

在开始编程之前,您需要了解 选择的编程环境是如何工作的。例如,使用此脚本:

#!/usr/bin/env perl

use strict;
use warnings;

print join('|', @ARGV), "\n";
zsh中的

 ./1tt.pl name1 "name2 and name3"
name1|name2 and name3

也就是说,脚本有两个参数。 name1name2 and name3。双引号字符串作为单个参数传递。另一方面,请参阅:

$ ./1tt.pl name1 "name2 and name3"
name1|name2 and name3
$ ./1tt.pl name1 "\"name2 and name3\""
name1|"name2 and name3"
$ ./1tt.pl name1 '"name2 and name3"'
name1|"name2 and name3"
$ ./1tt.pl name1 "'name2 and name3'"
name1|'name2 and name3'

另一方面,在Windows 10上,在cmd.exe窗口中:

C:\> perl t.pl name1 "name2 and name3"
name1|name2 and name3
C:\> perl t.pl name1 """name2 and name3"""
name1|"name2 and name3"
C:\> perl t.pl name1 "\"name2 and name3\""
name1|"name2 and name3"
C:\> perl t.pl name1 '"name2 and name3"'
name1|'name2 and name3'

答案 1 :(得分:1)

这里有两个问题 - 第一个是shell在将它们传递给perl之前先解开引号 。所以你需要逃避它们。

第二个是 - @ARGV在空格上分割。

所以要做你想做的事:

#!/usr/bin/env perl
use strict;
use warnings;

use Data::Dumper;

use Text::ParseWords qw ( quotewords ) ;

my $input =  "name1 \"name2 and name3\"";
my @words = quotewords ( " ", 0, $input );

print Dumper \@words;

或阅读@ARGV

#!/usr/bin/env perl
use strict;
use warnings;

use Data::Dumper;
use Text::ParseWords qw ( quotewords ) ;

my @words = quotewords ( " ", 0, join (" ", @ARGV) );

print Dumper \@words;

答案 2 :(得分:0)

您的代码段无效,因为$参数未定义。但是我尝试了这个更新,它可以按你的需要工作。请参阅以下输出:

#!/usr/bin/perl

use strict;
use warnings;
#use Data::Dumper;

my $argument_list = join(" ",@ARGV);

print "$argument_list\n";

这是输出:

$ perl test1.pl name1 \"name2 and name3\"
name1 "name2 and name3"
$ perl test1.pl name1 name2 and name3
name1 name2 and name3

答案 3 :(得分:0)

我稍微改变了你的代码以说明要点:

for ($c=0; $c<=$#ARGV; $c++) {print "ARGV[$c] = $ARGV[$c]\n";}
my $argument_list = join(" ",@ARGV);
print "$argument\n"; # you meant argument_list
print "ArgLst = $argument_list\n";

$ perl test.pl 1  two       "3 four" " 5 six"
ARGV[0] = 1
ARGV[1] = two
ARGV[2] = 3 four
ARGV[3] =  5 six

ArgLst = 1 two 3 four  5 six

注:

  1. 没有引号,参数由空格分隔
  2. 引用强制解释器将引用中的字符(包括空格)视为一个字符串
  3. “join”命令将参数连接在一起。单单看看ArgLst,你就无法分辨哪个是第二个参数。
  4. 我不完全了解你的问题。我希望代码间接回答你的问题。

答案 4 :(得分:0)

哦,我想我知道你现在的样子。

$ perl test1.pl name1 "\"n2 and n3\"" 
$ name1 "n2 and n3"

1st&amp;最后一个双引号用于字符串\“是一个字符,而不是分隔符的一部分。更优雅的是,你可以如下:

$ perl test1.pl name1 '"n2 and n3"'
$ name1 "n2 and n3"