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

发布于 2025-01-20 15:16:11 字数 265 浏览 3 评论 0原文

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

cat >/tmp/file <<EOL
foo

bar

baz

qux

quux
EOL

# some command

预期输出:

bar

baz

qux

How to output N(e.g. 2) lines surrounding a specific known line number(e.g. 5) in a file?

cat >/tmp/file <<EOL
foo

bar

baz

qux

quux
EOL

# some command

Expected output:

bar

baz

qux

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

春庭雪 2025-01-27 15:16:11

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

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

将输出3rd ,file.txt的第四,第五,第六和第7行。

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

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

说明:我将n设置为5,然后我使用 range n-2 th行(包含> n+2 TH行(包含),没有提供任何措施,这等效于{print}

If you know the line and number of lines in advance and thus you are able to compute the number of the first line and number of the last line you might use simple GNU sed command, for example

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

will output 3rd, 4th, 5th, 6th and 7th line of file.txt.

If you wish to change the line number then I would use GNU AWK following way

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

Explanation: I set n to 5 then I use Range to select lines from n-2th line (inclusive) to n+2th line (inclusive), no action is provided which is equivalent of giving {print}.

只有一腔孤勇 2025-01-27 15:16:11

稳健、可移植且高效地打印上下文(目标行两侧的行数相同):

$ 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 不会浪费在打印所需的行后,不必要地读取输入文件的其余部分。

Robustly, portably, and efficiently printing a context (same number of lines either side of a target line):

$ 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

or different numbers of lines before and after the target line:

$ 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

In particular for efficiency note:

  1. The math to calculate the begin/end line numbers is done once in the BEGIN section rather than recalculated every time a line is read, and
  2. The NR==end{exit} instead of NR==end{f=0} or similar so awk doesn't waste time unnecessarily reading the rest of the input file after the desired lines have been printed.
我很OK 2025-01-27 15:16:11

不带行号前缀:

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

Without line number prefixes:

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

baz

qux

With line number prefixes:

awk -v nr=5 'FNR>=nr-2 && FNR<=nr+3{ print FNR":"$0 }' /tmp/file
3:bar
4:
5:baz
6:
7:qux
终遇你 2025-01-27 15:16:11

这可能对您有用(gnu sed and bash):

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

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

另一种方法是使用GREP:

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

使用SED中的文件中的第5行,然后GREP 2行上下文的两条线。

This might work for you (GNU sed and bash):

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

Which fetches the range +/- 2 lines from line 5 of file.

Another way is to use grep:

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

Find line 5 in file using sed and then grep 2 lines of context either side of that line.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文