0

我有一个带有几个 Perl 脚本和几个 Perl oneliners 的 shell 脚本。shell 脚本中很少有 Perl 脚本在开始时有我使用过的单行符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

例如,如果abc.loneliner 中使用的文件是 and 的公共输入test.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 脚本时在命令行中提供输入???

提前致谢。

4

3 回答 3

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 变量。您可以在内程序中使用 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 );
于 2012-08-21T02:04:17.627 回答
0

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

FILE=$1
perl trial.pl $FILE
于 2012-08-21T02:07:51.653 回答
0

我相信您正在寻找$@传递参数:

设置:

run_me

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

测试.pl

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

测试2.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 和你的单行

于 2012-08-21T02:27:37.390 回答