假设我有一行文件:
db.collection.aggregate([
{$group: {_id: "$relate_id", userid: {"$push": "$userid"}}},
]
)
当我执行a1 - first match /a/
b - other stuff
a2 - last match /a/
b
c - first match /c/
c - last match /c/
时,我会得到
awk '/a/,/c/' file
我想要做的是获得/ a /和/ c /之间的中间部分。但模式/ a /和/ c /匹配几行,在这些行之间还有其他一些东西。所以我想知道是否有一种简单的方法来得到这样的结果:
a1 - first match /a/
b - other stuff
a2 - last match /a/
b
c - first match /c/
答案 0 :(得分:1)
您无法使用范围表达式执行此操作。您需要匹配a
并开始收集变量中的行。如果您遇到另一个a
,则必须清除该变量并重新开始。最后,当您看到c
时,您打印变量。
awk '/^a/ { var = $0; flag = 1; next }
flag { var = var "\n" $0 }
/^c/ && flag { print var; flag = 0; var = "" }' file
答案 1 :(得分:0)
由于你没有办法知道哪个是最后一次出现模式,直到你读完所有文件,最好经历两次:第一次得到匹配的行号第二个打印那些内容:
awk 'FNR==NR && /^a/ {p1=FNR; next} # last match of /a/
FNR==NR && /^c/ && !p2 {p2=FNR; next} # first match of /c/
(FNR >= p1) && (FNR <= p2)' file file
使用技巧FNR==NR
区分第一个循环和第二个循环,如Idiomatic awk中所述。
使用此文件返回:
$ awk 'FNR==NR && /^a/ {p1=FNR; next} FNR==NR && /^c/ && !p2 {p2=FNR; next} (FNR >= p1) && (FNR <= p2)' file file
a2 - last match /a/
b
c - first match /c/
答案 2 :(得分:0)
数组中的另外awk
个累积行
$ awk '/^a/{delete a; c=0; p=1}
p{a[++c]=$0}
/^c/{for(k=1;k<=c;k++) print a[k]; exit}' file
a2 - last match /a/
b
c - first match /c/