grep 返回匹配前后的第 N 行和第 M 行

grep 返回匹配前后的第 N 行和第 M 行

我知道使用 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

相关内容