我知道使用 grep 我可以使用字段-A
并-B
从匹配项中提取前一行和下一行。
但是,他们会根据指定的线条数来提取比赛之间的所有线条。
grep -r -i -B 5 -A 5 "match"
我想除了接收匹配的行之外,还仅接收匹配前的第 5 行和匹配后的第 5行,而不接收中间的行。
有没有办法用 来做到这一点grep
?
答案1
如果:
cat file
a
b
c
d
e
f match
g
h
i match
j
k
l
m
n
o
然后:
awk '
{line[NR] = $0}
/match/ {matched[NR]}
END {
for (nr in matched)
for (n=nr-5; n<=nr+5; n+=5)
print line[n]
}
' file
a
f match
k
d
i match
n
答案2
这基本上是 Glenn 的解决方案,但用 Bash、Grep 和 sed 实现。
grep -n match file |
while IFS=: read nr _; do
sed -ns "$((nr-5))p; $((nr))p; $((nr+5))p" file
done
注意,行号小于 1 将导致 sed 错误,而行号大于文件行数将导致不打印任何内容。
这只是最低限度。要使其递归工作并处理上述行号情况,需要做一些工作。
答案3
仅使用 是无法完成的grep
。如果ed
是一个选项:
ed -s file << 'EOF'
g/match/-5p\
+5p\
+5p
EOF
该脚本的基本内容是:对于 /match/ 的每一次匹配,打印该行前 5 行,然后打印该行后 5 行,然后打印该行后 5 行。
答案4
使用@glenn 的示例文本文件并使用 perl 而不是 awk:
$ perl -n0E 'say /(.*\n)(?=(?:.*\n){4}(.*match.*\n)(?:.*\n){4}(.*\n))/g' ex
将得到相同的结果,但运行速度更快:
a
f match
k
d
i match
n