在两个重复模式之间提取线条

时间:2017-09-01 09:13:37

标签: bash awk

我需要从大日志文件中提取“表”。表由以下行分隔:

IMPRESSION DE LA TABLE TSTR

以及第4次出现此行:

--------- ---------------------------------------------------------------

我无法找到更准确的表格定义。

例如,我的日志文件包含:

SOME
TEXT
BEFORE
IMPRESSION DE LA TABLE TSTR                   1323
--------- ---------------------------------------------------------------
POSITION |          INDICE                   |          ARGUMENT
--------- ---------------------------------------------------------------
         | TYPE     |  VALEUR                | TYPE     |  VALEUR
--------- ---------------------------------------------------------------
    1    | CHAINE   | COMPTEUR1              | ENTIER   | 0
    2    | CHAINE   | COMPTEUR2              | ENTIER   | 0
    3    | CHAINE   | RHO_1                  | TABLE    | 5187
    4    | CHAINE   | RHO_2                  | TABLE    | 6029
--------- ---------------------------------------------------------------
ANY
OTHER
TEXT
FOLLOWS

我想得到:

IMPRESSION DE LA TABLE TSTR                   1323
--------- ---------------------------------------------------------------
POSITION |          INDICE                   |          ARGUMENT
--------- ---------------------------------------------------------------
         | TYPE     |  VALEUR                | TYPE     |  VALEUR
--------- ---------------------------------------------------------------
    1    | CHAINE   | COMPTEUR1              | ENTIER   | 0
    2    | CHAINE   | COMPTEUR2              | ENTIER   | 0
    3    | CHAINE   | RHO_1                  | TABLE    | 5187
    4    | CHAINE   | RHO_2                  | TABLE    | 6029
--------- ---------------------------------------------------------------

我发现了一些想法:

How to select lines between two patterns?

Extract lines between two patterns from a file

但它们都不允许找到第n次出现的模式。

另请注意,我的文件中有其他表格(包含其他名称),我不想提取。

3 个答案:

答案 0 :(得分:3)

awk 方法:

awk '/^IMPRESSION DE LA TABLE TSTR/{f=1}f && /^-/ && ++c==4{print; f=c=0}f' file

输出:

IMPRESSION DE LA TABLE TSTR                   1323
--------- ---------------------------------------------------------------
POSITION |          INDICE                   |          ARGUMENT
--------- ---------------------------------------------------------------
         | TYPE     |  VALEUR                | TYPE     |  VALEUR
--------- ---------------------------------------------------------------
    1    | CHAINE   | COMPTEUR1              | ENTIER   | 0
    2    | CHAINE   | COMPTEUR2              | ENTIER   | 0
    3    | CHAINE   | RHO_1                  | TABLE    | 5187
    4    | CHAINE   | RHO_2                  | TABLE    | 6029
--------- ---------------------------------------------------------------

答案 1 :(得分:2)

根据您的输入,这个应该有效:

awk '/^IMPRESSION DE LA TABLE TSTR/{ p = 1 };/^\-/{ c++; if ( c == 4  ){ print $0; c = 0; p = 0} }p'

输出:

IMPRESSION DE LA TABLE TSTR                   1323
--------- ---------------------------------------------------------------
POSITION |          INDICE                   |          ARGUMENT
--------- ---------------------------------------------------------------
         | TYPE     |  VALEUR                | TYPE     |  VALEUR
--------- ---------------------------------------------------------------
    1    | CHAINE   | COMPTEUR1              | ENTIER   | 0
    2    | CHAINE   | COMPTEUR2              | ENTIER   | 0
    3    | CHAINE   | RHO_1                  | TABLE    | 5187
    4    | CHAINE   | RHO_2                  | TABLE    | 6029
--------- ---------------------------------------------------------------

说明:

当看到以IMPRESSION DE LA TABLE TSTR开头的一行时,这个开始打印。然后它计算以 - 开头的行 - 直到第四次出现。当到达第四个时,打印该行并将计数器再次设置为零。此外,p设置为0,因此打印将被禁用,直到下一行以IMPRESSION DE LA TABLE TSTR开头。

答案 2 :(得分:0)

Perl救援:

perl -ne '
    ($table, $line) = (1, 0) if /IMPRESSION DE LA TABLE TSTR/;
    ++$line if /^-{9} -{63}$/;
    print if $table;
    ($table, $line) = () if 4 == $line;
' -- file