【问题标题】:Perl match file content using grep or read line by linePerl 使用 grep 匹配文件内容或逐行读取
【发布时间】:2020-05-14 08:36:23
【问题描述】:

我有一个包含以下内容的文件。根据特定条件,我想提取 column1 数据。

输入文件:

RT0AC1 127.0.0.1
RT1AB1 127.0.0.1
RT2AC1 127.0.0.1
RT3AC3 127.0.0.1
ST1AC1 127.0.0.1
WA1RA1 127.0.0.1
WB1RQ1 127.0.0.1
WG3RA3 127.0.0.1

需要的数据:

RT0AC1
RT2AC1
RT3AC3
ST1AC1
WA1RA1
WG3RA3

这里我写了一个 Perl 脚本,它可以将数据存储在$data 中。但无法将数据写入out_file.txt

#!/usr/bin/perl

use strict;
use warnings;

my $data = system('grep "AC\|RA" file.txt  | awk -F" " \'{if((substr($1,4,2) == "AC")||(substr($1,4,2) == "RA")){print $1}}\'');

print $data;

my $file = "out_file.txt";
open my $fh, ">:encoding(utf8)", $file or die "$file: $!";

print $fh $data;
close $fh;

#script continues..

out_file.txt 的内容为空白。我做错什么了吗?

您是否建议我逐行阅读file.txt内容并使用regex匹配内容并将内容写入out_file.txt而不是使用grep进行搜索。

哪个会更快?

编辑

这不是我的剧本的结尾。我需要在我的脚本中做进一步的处理。因此,如果您建议 perl one liner 或 awk 我需要按照建议的方式执行 @toolic 。

【问题讨论】:

  • @toolic 酷。这样可行。性能怎么样?任何建议。
  • perl -ne "/^(\w{2}\d(AC|RA)\d)\b/ && print \"$1\n\"" file.txt > out_file.txt
  • perl -ne "/^(\S+)/ && print \"$1\n\"" file.txt > out_file.txt -- 如果您需要没有任何条件的第一列。
  • 我绝对支持 glenn-jackman 的回答中关于不从 Perl 脚本中调用 grepawk 的评论,该脚本非常有能力进行这种处理(如答案所示)。

标签: perl file-io


【解决方案1】:

从 perl 中调用 grep 和 awk 是没有意义的:

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

my @data;
open my $fin,  "<:encoding(utf8)", "file.txt";
while (<$fin>) {
    my $word = (split)[0];
    my $code = substr($word, 3, 2);
    push @data, $word if grep {$_ eq $code} qw(AC RA);
}
close $fin;

open my $fout, ">:encoding(utf8)", "out_file.txt";
print $fout join("\n", @data), "\n";
close $fout;

【讨论】:

  • 这很好地不需要正则表达式,或者可以在正则表达式中完成所有操作:my ($w, $c) = /(.{3}(AC|RA).)/; push @data, $w if $c;,甚至if ( my ($w) = /(.{3}(AC|RA).)/ ) { push @data, $w }。我想知道正则表达式的启动成本与split+substr+grep 相比如何——更重要的是,可读性如何比较。 (不是批评,只是大声想知道。)
  • (在第二种情况下应该是/(.{3}(?:AC|RA).)/。此外,可能希望用\S+ 或其他更具体的模式替换最后一个.,具体取决于问题说明)
  • @zdim 您是否建议我使用split+substr+grep 而不是使用问题中提到的awk+grep。由于此脚本每半小时运行一次,输入文件太长。所以我也想考虑一下脚本的性能。
  • @vinodk89 我绝对建议在 Perl 中进行处理(而不是调用 awk+grep)——它在各方面都好得多。一方面,我希望调用这些外部程序只会 slower ,因为它会产生很多额外的工作。计时。但重要的是,这比精心设计一条调用复杂的外部工具组合的线路更好。这很清楚,出错的机会要少得多,需要时更容易更改,更可靠......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-04
  • 2020-04-08
相关资源
最近更新 更多