繁体   English   中英

如何检查条件,然后使用awk在带有条件的行之前的行中打印特定字段?

[英]How to check a condition and then print specific fields in lines before the line with the condition using awk?

我有一个带有以下输出的文件:

58.752391 0.000  1 1  6.152565 2.757839 14.558406 0.000000 2.156979  0.000000 0.000000  0 0 0  1
16.089417316313 0.000000000000 6.171292860915 2.757949885550  -150168 0
6.953218e-310 0.000000e+00 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0 0 0 0 0.000000   0.000000 0.000000  0
0.000000 0.000000 0 0 0 0 0.000000   0.000000 0.000000  0
-1.000000 -1.000000
0 

14034.172996 0.000  13 13  1.107936 1.107936 -1.000000 -1.000000 -1.000000  23.670258 34.172995  0 0 0  0
3085.963203076240 0.667625281751 10.905159250868 8.915904022910  -150168 639
6.953218e-310 0.000000e+00 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
3.120454 8.844320 8 1 127.895 0 23.670258   1.107936 0.000000  0
1.107936 8.390152 13 5 1e+50 0 34.172995   1.107936 0.000000  0
-1.000000 -1.000000
3 CE1(5-1;8-1) SN1 SN2 

等等...

我想检查第6行(然后每8行)中的两个数字是否不同于-1.000000。 如果是这样,根据哪个(第一个,第二个或两个)不同,我想产生以下输出:

1)第一个数字不同于-1.000000:

这个不同的数字,在此数字之前的4行-第三列(在此示例中为6.171292860915,如果该数字不同于-1.000000),在此数字之前的2行-第8列(在此示例中为0.000000),同一行-第7列,此号码后的行

2)第二个数字不同于-1.000000:

这个不同的数字,这个数字之前的4行-第四列,这个数字之前的1行-第8列,同一行-第7列,这个数字之后的行

3)第一个和第二个数字不同于-1.000000:

1)输出2)输出

我知道如何使用sed提取这些行,在我的示例中为-1.000000。 现在,我想我应该在sed命令中包含一些awk的ifs,以检查该行是否包含-1.000000或其他数字,然后打印我需要的内容。 但是,我不知道如何引用sed检查的行之前的行。 如果有任何帮助或线索,我将不胜感激。 谢谢!

Perl解救:

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

# Read in "paragraph mode".
$/ = q();

# Auto add newlines.
$\ = "\n";

while (<>) {
    my @lines = map [ split ], split /\n/;  # Create an array of arrays.
    if (-1 != $lines[5][0]) {
        print join ' ', $lines[5][0], $lines[1][2], $lines[3][7],
                        $lines[3][6], @{ $lines[6] };
    }
    if (-1 != $lines[5][1]) {
        print join ' ', $lines[5][1], $lines[1][3], $lines[4][7],
                        $lines[4][6], @{ $lines[6] };
    }
}

在awk中,变量NR保留行号,因此表达式

NR % 8 == 6 { ..... }

将选择第6、14、22行,依此类推。 您只需要一个计数器,但是变量会自动初始化为零,因此您将获得带有如下表达式的序号(第6行为1,第14行为2,依此类推)

++seqno

希望有帮助...

AWK的另一种解决方案

awk '{if(NR%8==2){a=$3;b=$4};if(NR%8==4){a=$8","$7","a};if(NR%8==5){b=$8","$7","b};if(NR%8==6){c=$1;d=$2};if(NR%8==7){if(c!=-1.000000)print a,$0;if(d!=-1.000000)print b,$0 }}' inputfilename

如果我如下打破上面的命令

awk '{
     if(NR%8==2){a=$3;b=$4};
     if(NR%8==4){a=$8","$7","a};
     if(NR%8==5){b=$8","$7","b};
     if(NR%8==6){c=$1;d=$2};
     if(NR%8==7){
               if(c!=-1.000000)print a,$0;
               if(d!=-1.000000)print b,$0 
                }
     }' inputfilename

我从头开始将输出详细信息存储在a和b中,同时逐行读取文件,例如NR%8 == 2是第2行,NR%8 == 4是文件的第4行,依此类推。 在第7行(NR%8 == 7),我正在检查从第6行存储的值c和d(NR%8 == 6),如果c和d值不匹配,我们将在第7行内容中打印输出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM