Shell/Bash命令获取STDOUT的第n行

Ala*_*orm 194 bash shell stdout sed

是否有任何bash命令可以让你获得STDOUT的第n行?

也就是说,会采取这种做法

$ ls -l
-rw-r--r--@ 1 root  wheel my.txt
-rw-r--r--@ 1 root  wheel files.txt
-rw-r--r--@ 1 root  wheel here.txt
Run Code Online (Sandbox Code Playgroud)

并做一些类似的事情

$ ls -l | magic-command 2
-rw-r--r--@ 1 root  wheel files.txt
Run Code Online (Sandbox Code Playgroud)

我知道在编写要重用的脚本时这是不好的做法,但是当我每天使用shell时,能够以这种方式过滤我的STDOUT对我来说是有用的.

我也意识到这将是半简单的命令写入(缓冲区STDOUT,返回一个特定的行),但我想知道是否有一些标准的 shell命令来执行此操作,而无需我将脚本放到位.

Jon*_*ler 308

使用sed,只是为了变化:

ls -l | sed -n 2p
Run Code Online (Sandbox Code Playgroud)

使用此替代方案,由于在打印所需行时停止读取输入,因此看起来更有效,可能会在馈送过程中生成SIGPIPE,这可能反过来生成不需要的错误消息:

ls -l | sed -n -e '2{p;q}'
Run Code Online (Sandbox Code Playgroud)

我经常看到我经常使用第一个(无论如何都更容易打字),虽然ls它不是一个在获得SIGPIPE时抱怨的命令.

对于一系列行:

ls -l | sed -n 2,4p
Run Code Online (Sandbox Code Playgroud)

对于几个范围的线:

ls -l | sed -n -e 2,4p -e 20,30p
ls -l | sed -n -e '2,4p;20,30p'
Run Code Online (Sandbox Code Playgroud)

  • `n` 表示不打印所有其他行 (5认同)
  • @LeoUfimtsev:`p`是`sed`语句,用于打印由其前面的行范围标识的行.因此,"2,4p"表示打印行2,3,4. (3认同)

mob*_*mob 79

ls -l | head -2 | tail -1
Run Code Online (Sandbox Code Playgroud)

  • +2,但我建议`head -n 2 | tail -n 1` - 现代的头部和尾部往往会发出警告. (13认同)
  • 关于*nix命令行的好处:百万和一种方法来做所有事情,每个人都有一个喜欢和讨厌所有其他方式... :-) (12认同)
  • 头用管道拖尾?可怕.多种更好的方法. (3认同)
  • 使用两个过程来过滤数据有点过分(但是,鉴于现在机器的强大功能,他们可能会应对).推广处理一个范围并不是完全无关紧要的(对于范围N..M,你使用`head -n M | tail -n M-N + 1`),并且不可能推广处理多个范围. (2认同)

Chr*_*heD 39

替代漂亮的头/尾方式:

ls -al | awk 'NR==2'
Run Code Online (Sandbox Code Playgroud)

要么

ls -al | sed -n '2p'
Run Code Online (Sandbox Code Playgroud)


Mar*_*gar 21

来自sed1line:

# print line number 52
sed -n '52p'                 # method 1
sed '52!d'                   # method 2
sed '52q;d'                  # method 3, efficient on large files
Run Code Online (Sandbox Code Playgroud)

来自awk1line:

# print line number 52
awk 'NR==52'
awk 'NR==52 {print;exit}'          # more efficient on large files
Run Code Online (Sandbox Code Playgroud)

  • Upvote用于添加停止大文件的功能. (5认同)
  • `exit`对于大文件来说是一个很棒的技巧 (3认同)

Mic*_*ker 8

为了完整起见;-)

更短的代码

find / | awk NR==3
Run Code Online (Sandbox Code Playgroud)

寿命缩短

find / | awk 'NR==3 {print $0; exit}'
Run Code Online (Sandbox Code Playgroud)


小智 7

另一张海报建议

ls -l | head -2 | tail -1
Run Code Online (Sandbox Code Playgroud)

但如果将 head 插入 tail,看起来 N 行之前的所有内容都会被处理两次。

将尾巴插入头部

ls -l | tail -n +2 | head -n1
Run Code Online (Sandbox Code Playgroud)

会更有效率吗?


Pau*_*ce. 6

试试这个sed版本:

ls -l | sed '2 ! d'
Run Code Online (Sandbox Code Playgroud)

它说"删除所有不是第二行".


Hai*_* Vu 6

你可以使用awk:

ls -l | awk 'NR==2'
Run Code Online (Sandbox Code Playgroud)

更新

由于一个错误,上面的代码不会得到我们想要的:ls -l命令的第一行是总行.为此,以下修订后的代码将起作用:

ls -l | awk 'NR==3'
Run Code Online (Sandbox Code Playgroud)