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



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

cat >/tmp/file <<EOL
foo
bar
baz
qux
quux
EOL
# some command

预期产出:

bar
baz
qux

如果你事先知道行数和行数,因此你能够计算第一行的数量和最后一行的数量,你可以使用简单的 GNUsed命令,例如

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

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

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

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

说明:我将n设置为5,然后使用范围选择从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 部分中完成一次,而不是在每次读取行时重新计算,并且
  2. NR==end{exit}而不是NR==end{f=0}或类似,因此awk不会浪费时间在打印所需行后不必要地读取输入文件的其余部分。

不带行号前缀:

awk -v nr=5 'FNR>=nr-2 && FNR<=nr+3{ print $0 }' /tmp/file
bar
baz
qux
<小时 />

带行号前缀:

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

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

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

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

另一种方法是使用 grep:

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

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

最新更新