查找和删除符合条件的行

时间:2012-06-22 11:51:53

标签: linux perl bash sed awk

我有三个不同的文件,其中包含数字列。这些文件非常大(其中包含50,000,000多行)

作为示例,数据格式类似于

1.2 22.333 10002.3432 223.2111
50.2166 2.873 15402.3432 322.1
.
.
.

对于每个文件(file1,file2和file3),我需要执行以下操作:

FILE1   找到包含任何数字x< = 1000的行,并从file1

中删除这些行

FILE2 找到包含任何数字x> = 1800的行,并从file2中删除行

FILE3 找到包含任意数字1000< = x< = 1800的行,并从file3中删除这些行。

我对REGEX的了解不足以弄清楚如何快速实现这一目标。非常感谢任何帮助。

4 个答案:

答案 0 :(得分:6)

正如其他人在评论中所提到的,正则表达式在这种情况下并不理想。

以下是使用awk执行此操作的一种方法:

awk '{for (i=1;i<=NF;i++) {if ($i<=1000) next}; if (NF) print}' file1 > new1

解析file并禁止任何包含数字<= 1000(和空行)的行。然后将输出传送到新文件。

对于file2file3,只需更改相关if语句中的条件即可符合您的要求。


以下是一个快速解释:

         This is repeated for each line in the input file
                                |
      -------------------------------------------------------
     /                                                       \
awk '{for (i=1;i<=NF;i++) {if ($i<=1000) next}; if (NF) print}'
      ------------------   ------------------   -------------
             |                     |                  |
     for each field/column         |                  |
                                   |                  |
                      If condition is met, skip       |
                             this line                |
                                                      |
                                          otherwise, if the line is
                                          not empty (number of fields != 0)
                                          print out the whole line.

答案 1 :(得分:5)

输入文件“sample”的位置为:

500 500 500
1000 1000 1000
2000 2000 2000
3000 3000 3000

剥离x <= 1000

$ awk '{ for (i=1; i<=NF; i++) { if ($i <= 1000) next } print }' < sample
2000 2000 2000
3000 3000 3000

剥离x >= 1800

$ awk '{ for (i=1; i<=NF; i++) { if ($i >= 1800) next } print }' < sample
500 500 500
1000 1000 1000

剥离1000 <= x <= 1800

$ awk '{ for (i=1; i<=NF; i++) { if (1000 <= $i && $i <= 1800) next } print }' < sample
500 500 500
2000 2000 2000
3000 3000 3000

答案 2 :(得分:3)

这是一个相当短的Perl脚本,它输出你的FILE3:

#!/usr/bin/perl

use warnings;
use strict;

our $lower = 1000.0;
our $upper = 1800.0;

OUTER: while (<>) {
    $_ >= $lower && $_ < $upper and next OUTER for /(\S+)/g;
    print;
}

您可以调整FILE1和FILE2。

(无论好坏,我的脚本都是基本的Perl习惯用法,尽管脚本简洁,但如果你不了解Perl,它几乎是不可读的。不过,这就是用Perl编写的,你会用脚本语言做的一个人怀疑,享受学习。)

答案 3 :(得分:0)

以下脚本之类的东西应该适合你。

#!/usr/bin/perl
while(<>) {
    my $line = $_;
    foreach my $col (split ' ', $line){     #for each column
        unless ($col <= 1000) {
            print $line;
        }
        #add other statements for other files
    }
}

修改 - 提高代码效率感谢TLP