awk模式匹配语法c&&! - c

时间:2014-02-07 18:16:51

标签: regex bash awk

可能很简单,但我找不到答案......

在Bash脚本中运行这个常见的awk one liner以在模式之后打印第N行

awk 'c&&!--c;/pattern/{c=5}' infile

这样可以在模式后返回第5行。我真正需要做的是返回模式之后的第5,7,8,16,18和19行!

我可以通过使用六个Awk命令并将结果捕获到一个文件然后将其用作其余脚本的infile来实现这一点但这看起来很愚蠢。

有什么想法吗?

5 个答案:

答案 0 :(得分:1)

我想我会这样做:

BEGIN { last = 19; lines[5] = lines[7] = lines[8] = lines[16] = lines[18] = lines[last] = 1; }

f && ++c in lines { print; if (c == last) exit}
/pattern/ { f = 1; }

答案 1 :(得分:1)

$ seq 100 | 
  awk -v patt='^10|50$' '
      BEGIN {p[5];p[7];p[8];p[16];p[18];p[19]} 
      $0 ~ patt {n=NR} 
      n && (NR-n) in p
'
15
17
18
26
28
29
55
57
58
66
68
69

答案 2 :(得分:1)

对@ GlennJackman的例子略有语法扭曲:

$ seq 100 | 
  awk -v patt='^10|50$' '
      BEGIN {split("5 7 8 16 18 19",offsets)} 
      $0 ~ patt {for (i in offsets) p[NR + offsets[i]]} 
      NR in p
'
15
17
18
26
28
29
55
57
58
66
68
69

答案 3 :(得分:0)

试试这个awk:

awk '!p && /pattern/{p=1;c=0} c ~ /^([578]|1[689])$/ {print; if (c==19) exit} p{c++}' infile

<强>解释

  • !p && /pattern/ - 如果第一次设置模式设置p = 1并初始化计数器c = 0
  • p{c++} - 如果已找到模式,则递增计数器
  • c ~ /^([578]|1[689])$/ - 如果计数器是5,7,8,16,18,19之一
  • {print; if (c==19) exit} - 对于那些计数器打印行并存在于第9行之后

答案 4 :(得分:0)

pattern找到

之后打印第2,4和6行
awk 'BEGIN {a="2 4 6";split(a,b," ")} /pattern/ {f=NR} f {for (i in b) if (f+b[i]==NR) print}' file

cat file
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine
10 ten

搜索three

awk 'BEGIN {a="2 4 6";split(a,b," ")} /three/ {f=NR} f {for (i in b)  if (f+b[i]==NR) print}'
5 five
7 seven
9 nine

这很容易扩展,只需将您喜欢的数字添加到变量a

即可

这是如何运作的:

awk '
BEGIN {                 # Begin block
    a="2 4 6"           # Set variable a
    split(a,b," ")      # Split the variable a into array b
    } 
/pattern/               # if pattern is found and f is not set do
    f=NR                # Set f=1 (to prevent this block to be run 
f   {                   # If f is true (pattern is found)
    for (i in b)        # loop trough all lines to find
        if (f+b[i]==NR) # id line number found f + line in array b is equal to current line number
            print       # print the line
    }' file             # the input file