仅当第二个模式最后一列满足条件时,在两个模式之间打印行

时间:2014-01-17 04:28:35

标签: regex sed awk

文件如下:

#########################################
some text 

some text

........

/pattern1/ some text here also in this line

some more text

some more text

/pattern2/ some text last_column/file


some text 

some text

.........

/pattern1/

some text

.....

.....

/pattern2/ some text last_column/filed

###########################################

注意:

  1. Last_column / field始终为数值。
  2. 模式pattern1,pattern2&模式之间的某些线条肯定会存在。
  3. 有谁可以帮帮我吗? 我需要以下输出

    1. 我需要打印pattern1和pattern2之间的所有行
    2. 我只需要在pattern2匹配行中的最后一列/字段大于10时打印pattern1和pattern2之间的行,如果条件不满足,我不想在这些模式之间打印行。即,pattern2匹配行的最后一列/字段小于10。
    3. awk,sed,grep一切都很好。

2 个答案:

答案 0 :(得分:1)

第一个是微不足道的:

sed -n '/pattern1/,/pattern2/p' input-file

对于第二个,我会这样做:

tac input-file | 
awk '/pattern2/ && $NF > 10 { p=1} p; /pattern1/{p=0}' |
tac

如果您无权访问tac(只是反转输入行),您可以这样做:

awk '/pattern1/{p=1}
p{ b = sprintf( "%s%s\n", b, $0 )}
/pattern2/ { if( $NF > 10 && p ) printf "%s", b; b=""; p=0 }' input-file

答案 1 :(得分:1)

你可以使用grep的一些相当无痛的正则表达式来完成两者。

这些示例将打印到stdout

1: grep -Pzo '(?s)(?<=/pattern1/).*?(?=/pattern2/)' file

2: grep -Pzo '(?s)(?<=/pattern1/).*?(?=/pattern2/.*?[1-9][0-9]+)' file

说明

grep标记:

-P              --perl-regexp (extended regex functionality)
-z              ignore newlines (`\n`) in input
-o              print only the matched part

正则表达式:

(?s)            #PCRE_DOTALL (. matches any character)
(?<=            #Positive look-behind (match this pattern, but don't include in the output)
    /pattern1/  
)    
.*?             #Find 0 or more of . (any character) in "non-greedy" mode
(?=             #Positive look-ahead (match this pattern, but don't include in the output)
    /pattern2/
    .*?         #Find 0 or more of . (any character) in "non-greedy" mode
    [1-9][0-9]+ #Match a number greater than 10 (which would be comprised of 
                #   one digit 1-9 followed by any number of digits 0-9)
)