【问题标题】:How do I read double quotes(") or single quotes(') through command line into my perl program?如何通过命令行将双引号(“)或单引号(')读入我的 perl 程序?
【发布时间】:2017-06-08 10:47:46
【问题描述】:

我正在尝试使用作为命令行参数传递给我的脚本的使用参数,但是这样做时双引号(“)和单引号(')消失了。 例如在运行以下:

#!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" 作为另一个参数只会让情况变得更糟。

【问题讨论】:

  • 您的代码没有按照发布的方式编译和运行。你声称使用strict,但是,你有print "$argument\n";,但没有在任何地方声明$argument。最好不要对你正在寻求帮助的人撒谎。

标签: perl shell


【解决方案1】:

您看到的行为是您正在使用的 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'

【讨论】:

    【解决方案2】:

    这里有两个问题-第一个是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;
    

    【讨论】:

      【解决方案3】:

      您的代码 sn-p 不起作用,因为 $argument 未定义。但是我尝试了这个更新,它可以按你的意愿工作。请参阅下面的输出:

      #!/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
      

      【讨论】:

      • 感谢@SinanÜnür。更正了它。我没有在命令行上执行它,而是将它用作 perl 解释器的参数,因此它可以解决这个错误。
      【解决方案4】:

      我稍微更改了您的代码以说明要点:

      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,您将无法分辨哪个是第二个参数。

      我对你的问题不是 100% 了解。我希望代码能间接回答你的问题。

      【讨论】:

        【解决方案5】:

        哦,我想我知道你现在在追求什么了。

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

        第一个和最后一个双引号用于字符串,\" 是一个字符,而不是分隔符的一部分。更优雅的是,您可以如下所示:

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

        【讨论】:

          猜你喜欢
          • 2011-09-03
          • 1970-01-01
          • 2011-03-09
          • 2013-02-16
          • 2021-12-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多