如何在文件中输出围绕特定已知行号(例如 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
特别是效率说明:
- 计算开始/结束行号的数学运算在 BEGIN 部分中完成一次,而不是在每次读取行时重新计算,并且
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 行上下文。