使用system()在perl中运行“cat”命令会创建所需的文件,但它是空白的

时间:2013-07-09 09:51:34

标签: perl

我想通过我的Perl脚本运行两个shell命令,该脚本使用模式搜索创建find.txt文件。以下是shell脚本,它运行正常并在从shell运行时给出结果:

cat "/home/atsuser/Users/srittamp/ns.conf" | grep "add\|set\|enable" | awk '{print $2}' > find.txt
grep -o '\w*' find.txt | sort | uniq > find.txt

但是,当我使用perl的system命令执行相同操作时,我得到一个空白find.txt。以下是我的Perl脚本:

#!/usr/bin/perl

use strict;
use warnings;

my $conf_file = "/home/atsuser/Users/srittamp/ns.conf";
my $find_file = "/home/atsuser/Users/srittamp/find.txt";


system("cat \"$conf_file\" | grep \"add\\|set\\|enable\" | awk '{print \$2}' > /home/atsuser/Users/srittamp/find.txt");
system("grep -o \'\\w*\' $find_file | sort | uniq > /home/atsuser/Users/srittamp/find.txt");

有人可以帮我解决这个问题吗?

5 个答案:

答案 0 :(得分:2)

如何在Perl中执行:

#!/usr/bin/env perl

use strict;
use warnings;

use charnames qw( :full :short );
use English qw( -no_match_vars ) ;  # Avoids regex performance penalty

my $conf_file = "/home/atsuser/Users/srittamp/ns.conf";
my $find_file = "/home/atsuser/Users/srittamp/find.txt";

# cat "/home/atsuser/Users/srittamp/ns.conf" | grep "add\|set\|enable" | awk '{print $2}' > find.txt
# grep -o '\w*' find.txt | sort | uniq > find.txt

# save unique items
my %list = ();

open my $in_fh, '<', $conf_file or die "could not open $conf_file: $OS_ERROR\n";
while( my $line = <$in_fh> ){

    # grep "add\|set\|enable"
    if( $line =~ m{ add\|set\|enable }msx ){

        # awk '{print $2}'
        my @fields = split "\N{SPACE}", $line;
        $list{ $fields[1] } = 1;

    }
}
close $in_fh or die "could not close $conf_file: $OS_ERROR\n";

# output the sorted list
open my $out_fh, '>', $find_file or die "could not open $find_file: $OS_ERROR\n";
for my $item ( sort keys %list ){
  print {$out_fh} "$item\n" or die "could not print to $find_file: $OS_ERROR\n";
}
close $in_fh or die "could not close $find_file: $OS_ERROR\n";

答案 1 :(得分:2)

我甚至不会在您的系统命令中进入useless use of cat,或者您正在定义$find_file这一事实,而不是在system中使用变量命令,硬编码文件路径,或者使用sort | uniq时使用sort -u的事实。

我的问题是,当你可以轻松地完成所有工作时,为什么还要烦恼系统命令,并且直接在Perl中更有效地执行它?:

use strict;
use warnings;
use autodie;
use feature qw(say);
use constant {
    FIND_FILE  => '/home/atsuser/Users/srittamp/find.txt',
    CONF_FILE  => '/home/atsuser/Users/srittamp/ns.conf',
};

open my $conf_fh, "<", CONF_FILE;
my %conf_hash;
while ( my $line = <$conf_fh> ) {
    chomp $line;
    next unless line =~ /add|set|enable\s+(\w+)/;
    $conf_hash{$1} = $1;
}
close $conf_fh;

open my $find_fh, ">", FIND_FILE;
for my $config ( sort keys %conf_hash ) {
    say {$find_fh} $config;
}
close $find_fh;

由于我不知道conf.ns的格式,所以我不确定你到底在找什么,所以我的正则表达式匹配可能不是100%准确。

两个循环:第一个将您在哈希中寻找的任何内容存储为哈希键。这会解决唯一问题(sort | uniq)。第二种只是对存储的密钥进行排序并打印出来。

简单干净,也可能快得多。另外,我不会产生并等待其他两个进程完成,我的操作系统上不再存在依赖性问题。 Solaris version of grep doesn't have an - o`参数 1 ,Windows没有这些基本的Unix样式命令。


1 至少它不是我最近一次在Solaris上工作的那段时间了。

答案 2 :(得分:1)

@Slaven,我将它传输到一个新文件,现在正在运行。非常感谢你。这是代码:

\#!/usr/bin/perl

use strict;
use warnings;

my $conf_file = "/home/atsuser/Users/srittamp/ns.conf";
my $find_file = "/home/atsuser/Users/srittamp/find.txt";
my $find_file2 = "/home/atsuser/Users/srittamp/find2.txt";

system("cat \"$conf_file\" | grep \"add\\|set\\|enable\" | awk '{print \$2}' >   $find_file");
system("grep -o \'\\w*\' $find_file | sort | uniq > $find_file2");

现在find2.txt的结果正确。

如果有人能提出更简单的方法,我将不胜感激。问我是grep / awk / cat等的新手。

谢谢,

答案 3 :(得分:1)

执行此操作的更简单方法,甚至不涉及perl,因为完成所需内容的工具已经存在(尽管在perlpython中执行此操作可能会稍微提高效率如果你的文件非常大,那么实际编写/测试/调试它的工作要多得多一些):

awk '/add|set|enable/{print $2}' conf.txt | sort -u > find.txt

答案 4 :(得分:0)

这是我的配置文件:

set ns config -IPAddress 10.102.40.17 -netmask 255.255.255.0
enable ns feature WL SP LB CS SSL SSLVPN AppFw
enable ns mode L3 Edge USNIP PMTUD
set system parameter -natPcbForceFlushLimit 4294967295
set system user nsroot 114d02da8ec8def10b3fba5c29dfd9e6343484399ea3f79e3 -encrypted -timeout 0
set rsskeytype -rsstype ASYMMETRIC
set lacp -sysPriority 32768 -mac 00:30:48:b9:76:14
set ns hostName nk11p00it-nsc-ext001a
set interface 0/1 -throughput 0 -bandwidthHigh 0 -bandwidthNormal 0 -intftype "Intel 8247X" -ifnum 0/1
set interface 0/2 -throughput 0 -bandwidthHigh 0 -bandwidthNormal 0 -intftype "Intel 8247X" -ifnum 0/2
set interface 1/1 -throughput 0 -bandwidthHigh 0 -bandwidthNormal 0 -intftype "Intel 8247X" -ifnum 1/1
set interface 1/2 -throughput 0 -bandwidthHigh 0 -bandwidthNormal 0 -intftype "Intel 8247X" -ifnum 1/2
set interface 1/3 -throughput 0 -bandwidthHigh 0 -bandwidthNormal 0 -intftype "Intel 8247X" -ifnum 1/3
set interface 1/4 -throughput 0 -bandwidthHigh 0 -bandwidthNormal 0 -intftype "Intel 8247X" -ifnum 1/4

在这里,我想找到命令的第二个字,其中&#34;添加,设置和启用&#34;是第一句话。

所以,我正在搜索添加,设置,启用行,然后搜索这些行的第二个单词,最后消除重复项。

使用常量的问题是,ns.conf和我的find.txt存储的文件夹是在运行时动态生成的文件夹,然后在每次脚本运行结束时被删除。

例如,在我的实际脚本中,ns.conf和findn.txt将存储在以下文件夹中:

my $conf_file = "$SUITE_PATH/$test_instance_id/ns.conf";

其中,$ test_instance_id在运行时创建,这是一个唯一的数字,也是该运行的文件夹名称。