命令行 - 显示文件中已知确切行号周围的上下文行

Command line - show surrounding context lines in a file around known exact line number

如何输出文件中特定已知行号(例如5)周围的N(例如2)行?

cat >/tmp/file <<EOL
foo

bar

baz

qux

quux
EOL

# some command

预期输出:

bar

baz

qux

没有行号前缀:

awk -v nr=5 'FNR>=nr-2 && FNR<=nr+3{ print [=10=] }' /tmp/file
bar

baz

qux

带有行号前缀:

awk -v nr=5 'FNR>=nr-2 && FNR<=nr+3{ print FNR":"[=12=] }' /tmp/file
3:bar
4:
5:baz
6:
7:qux

如果您事先知道行数和行数,因此您可以计算出第一行的行数和最后一行的行数,您可以使用简单的 GNU sed 命令,例如

sed -n '3,7p' file.txt

会输出file.txt的第3、4、5、6、7行。

如果您想更改行号,那么我会按照以下方式使用 GNU AWK

awk 'BEGIN{n=5}NR==n-2,NR==n+2' file.txt

解释:我设置n为5然后我使用Range到select行从第n-2行(含)到第n+2行(含),没有提供等同于给出 {print}.

的操作

稳健、便携、高效地打印上下文(目标行两侧的行数相同):

$ awk -v tgt=5 -v ctx=2 '
    BEGIN{beg=tgt-(ctx=="" ? bef : ctx); end=tgt+(ctx=="" ? aft : ctx)}
    NR==beg{f=1} f; NR==end{exit}
' file
bar

baz

qux

或目标行前后行数不同:

$ awk -v tgt=5 -v bef=2 -v aft=4 '
    BEGIN{beg=tgt-(ctx=="" ? bef : ctx); end=tgt+(ctx=="" ? aft : ctx)}
    NR==beg{f=1} f; NR==end{exit}
' file
bar

baz

qux

quux

效率特别说明:

  1. 计算 begin/end 行号的数学运算在 BEGIN 部​​分完成一次,而不是每次读取一行时都重新计算,并且
  2. NR==end{exit} 而不是 NR==end{f=0} 或类似的,因此 awk 不会浪费时间在打印所需行后不必要地读取输入文件的其余部分。

这可能对你有用(GNU sed 和 bash):

sed -n $((5-2)),$((5+2))p file

从文件的第 5 行获取范围 +/- 2 行。

另一种方法是使用 grep:

greg -FC2 $(sed -n 5p file) file

使用 sed 在文件中找到第 5 行,然后在该行的两边查找 2 行上下文。