【问题标题】:Argument values to perl oneliners and shell scriptsperl oneliners 和 shell 脚本的参数值
【发布时间】:2012-08-16 08:08:00
【问题描述】:

我有一个带有几个 Perl 脚本和几个 Perl oneliners 的 shell 脚本。 shell 脚本中很少有 Perl 脚本在开头有 oneliners,我通过 system 使用过。这些脚本和 oneliners 必须采用共同的输入。那么有没有办法在shell脚本的命令行中给出参数值???

#!/bin/sh
perl test.pl
perl -ne 'print if/XXXX/ig../ZZZZZ/ig' abc.l > def.l
perl trial.pl
perl qwerty.pl

例如,如果在 oneliner 中使用的文件 abc.ltest.pltrial.pl 的公共输入,我可以使用参数值,以便我可以在命令行中将其提供给shell脚本中需要的代码????

我曾尝试为 Perl oneliner 分配参数,但输入未被接受。

我的test.pl代码如下

system( q( perl -ne '/^.QQQ/ig && print' abc.l > data1.l) );
system( q( perl -ne '/.SSS/ig && print' data1.l > data2.l) );
open(fh,"<data3.l");
open(fh1,">>data31.l");

while (my $string =<fh>)
{
...
..
..

我的 test.pl 也采用相同的输入 abc.l

谁能帮我解决这个问题?

  1. 如何在 Perl oneliners 中使用 ARGV?
  2. 如何在运行 shell 脚本时在命令行中提供输入???

提前致谢。

【问题讨论】:

  • 请以有意义的方式提出您的问题。
  • (1)我可以在 perl oneliners 中使用 ARGV 吗???... (2) 我可以在运行 Shell 脚本时在命令行中输入我的输入吗???
  • 如果您使用系统调用,您可能希望插入您传递给它的参数。

标签: perl shell command-line-arguments


【解决方案1】:

Perl 使用数组@ARGV 包含每个shell 参数的值:

$ perl -e 'print join (":", @ARGV) . "\n" ;' this is a test
this:is:a:test

如您所见,命令行中的所有参数均在@ARGV 中提取。

$ perl -e 'print "$ARGV[2]\n" ;' one two three four
three

这打印出第三个参数(因为@ARGV 计数从0 开始)。

这能回答你的问题吗?


附录

编辑:我的 test.pl 代码如下

system( q( perl -ne '/^.QQQ/ig && print' abc.l > data1.l) );
system( q( perl -ne '/.SSS/ig && print' data1.l > data2.l) );
open(fh,"<data3.l");
open(fh1,">>data31.l");

while (my $string =<fh>) {
...

为什么不简单地省略system 语句,只处理一次数据:

use strict;
use warnings;
use autodie;

open my $input_file, "<", "abc.1";
open my $output_file ">>", "data31.l"
while ( my $string = <$input_file> ) {
    chomp $string;

    # These skip over the lines you don't want
    # No need to "prep" your input first

    next unless $string =~ /^.QQQ/i;
    next unless $string =~ /.SSS/ig;
    # Here be dragons
    say $ouput_file "$something";
}
close $input_file;
close $output_file;

这更容易理解。您不再依赖于 system 命令,您无需创建一堆临时文件,而且由于您只遍历每一行一次,因此效率更高。


附录二

这是个好主意,但我有很多这样的单行器,我不确定我的代码在将单行器转换为代码后是否可以工作。那么他们是否有机会按照我问的方式做到这一点??????

如果我对您的理解正确,您想要一种方法来使用那些标准的内联 程序,显然是您在脚本中剪切和粘贴,然后以某种方式将第四个参数传递到您的主 Perl 程序中。

答案是system 命令生成一个 shell 以在分叉进程中运行该命令。父进程无法访问该分叉进程中的任何 Perl 变量。您可以在 inline 程序中使用 Perl 变量,这些变量可以在主程序中设置。

my $file1 = "data1.1";
my $file2 = "data2.1"
system qq( perl -ne '/^.QQQ/ig && print' abc.l > $file1 );
system qq( perl -ne '/.SSS/ig && print' $file1 >$file2; );

但是,如果这是您经常做的事情,那么我强烈建议您创建自己的包:

use local::fix_files qw(fix_QQQ fix_SSS);

fix_QQQ ( "abc.1", "data1.1" );
fix_SSS ( "data1.1", "data2.1 );

【讨论】:

  • 这回答了我 50% 的问题...如果这个 oneliner 在 perl 代码中使用,那么我可以在命令行中给出“perl test.pl 一二三四”
  • 我知道你在用系统命令做什么。为什么不简单地将system 命令代码放入您的程序中呢?见上文。
  • 这是个好主意,但我有很多这样的 oneliners,我不确定我的代码在将 oneliners 转换为代码后是否可以工作。那么他们有机会按照我问的方式来做吗? ??????
【解决方案2】:

shell 脚本的参数是 $1、$2 等。您可以按原样使用它们或将它们分配给变量,如下所示:

FILE=$1
perl trial.pl $FILE

【讨论】:

    【解决方案3】:

    相信你在找$@传递参数:

    设置:

    run_me

    #!/bin/sh
    perl test.pl $@
    perl test2.pl $@
    

    test.pl

    #!/usr/bin/perl
    print "test.pl: @ARGV\n\n";
    

    test2.pl

    #!/usr/bin/perl
    print "test2.pl: @ARGV\n\n";
    

    示例运行:

    %> ./run_me foo bar foobar
    test.pl: foo bar foobar
    
    test2.pl: foo bar foobar
    

    编辑/更新

    例如,如果在 oneliner 中使用的文件“abc.l”是 test.pl 和 trial.pl 的公共输入,我可以使用参数值,以便我可以在要使用的命令行中给出它通过shell脚本中所需的代码????

    我想你不明白上面发生了什么。 “run_me”是您的 shell 脚本,我们将三个值(“foo”、“bar”、“foobar”)传递给它。然后我们使用$@ 将这些值传递给perl 脚本。如果您想指定要传递的参数,而不是将所有值传递给 perl 脚本,您可以使用$n,其中n 是一个整数。因此,要将“bar”传递给 perl 脚本,您可以使用 $2

    举个例子:

    #!/bin/sh
    perl test.pl $1
    perl -ne 'print if/XXXX/ig../ZZZZZ/ig' $1 > def.l
    perl trial.pl
    perl qwerty.pl
    

    调用你的脚本:./shell_script abc.1
    abc.1 应该被传递给 test.pl 和你的one-liner

    【讨论】:

    • 这确实有帮助,但是如果 test.pl 有一个 oneliner 在开始时接受输入数据呢????我无法在 oneliner 中提供@ARGV。
    • @ARGV 与 perl 一起使用,发送到 perl 一个衬里(在 shell 脚本中)使用 $@。我可能没有正确理解你,所以你可能想举个例子。
    • 我已经编辑了我的帖子,我在其中放置了我的示例代码。如果你能举一个你评论过的oneliner的例子就好了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    • 2011-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多