是否有任何 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
并做类似的事情
$ ls -l | magic-command 2
-rw-r--r--@ 1 root wheel files.txt
我意识到在编写要重用的脚本时这是一种不好的做法,但是在日常使用 shell 时,能够以这种方式过滤我的 STDOUT 对我很有用。
我也意识到这将是一个简单的命令(缓冲 STDOUT,返回特定的行),但我想知道是否有一些标准的 shell 命令可以执行此操作,而无需我将脚本放置到位。
magic-command
这个词
使用 sed
,只是为了多样化:
ls -l | sed -n 2p
使用这种看起来更有效的替代方法,因为它在打印所需的行时停止读取输入,可能会在馈送过程中生成 SIGPIPE,这反过来可能会生成不需要的错误消息:
ls -l | sed -n -e '2{p;q}'
我经常看到我通常使用第一个(无论如何更容易键入),尽管 ls
不是一个在获得 SIGPIPE 时会抱怨的命令。
对于一系列行:
ls -l | sed -n 2,4p
对于几个范围的行:
ls -l | sed -n -e 2,4p -e 20,30p
ls -l | sed -n -e '2,4p;20,30p'
ls -l | head -2 | tail -1
head -n 2 | tail -n 1
——现代的正面和反面往往会发出警告。
head -n M | tail -n M-N+1
),并且无法泛化以处理多个范围。
$ ls -l | awk '{if (NR>=4 && NR<=64) print}'
(可以更轻松地添加更多条件,多个范围等......)
替代漂亮的头/尾方式:
ls -al | awk 'NR==2'
或者
ls -al | sed -n '2p'
'2p'
代表什么?
2
是一个变量怎么办?每个示例都使用单引号,但对于 var,您需要双引号。使用 var 时,我们可以“编程”awk 以使用单引号吗?示例 line =1; ls | awk 'NR==$line'
。我知道 bash
使用带变量的双引号。
为了完整起见;-)
更短的代码
find / | awk NR==3
寿命短
find / | awk 'NR==3 {print $0; exit}'
ls
— 最初的问题是关于某人的 STDOUT
,所以我认为最好让它更大。
{ print $0 }
,所以 `awk 'NR==3' 是一种更短的写法。
试试这个 sed
版本:
ls -l | sed '2 ! d'
它说“删除所有不是第二行的行”。
您可以使用 awk:
ls -l | awk 'NR==2'
更新
上面的代码不会得到我们想要的,因为一个错误: ls -l 命令的第一行是总行。为此,以下修改后的代码将起作用:
ls -l | awk 'NR==3'
Perl 对你来说很容易使用吗?
$ perl -n -e 'if ($. == 7) { print; exit(0); }'
显然用你想要的任何数字代替 7。
$ awk 'NR % 7' filename
来打印文件中的每 7 行。
另一张海报建议
ls -l | head -2 | tail -1
但是,如果您将头插入尾,则看起来直到第 N 行的所有内容都被处理了两次。
将尾巴插入头部
ls -l | tail -n +2 | head -n1
会更有效率吗?
是的,最有效的方法(正如 Jonathan Leffler 已经指出的那样)是将 sed 与 print & quit 一起使用:
set -o pipefail # cf. help set
time -p ls -l | sed -n -e '2{p;q;}' # only print the second line & quit (on Mac OS X)
echo "$?: ${PIPESTATUS[*]}" # cf. man bash | less -p 'PIPESTATUS'
唔
sed 在我的情况下不起作用。我提议:
对于“奇数”行 1,3,5,7... ls |awk '0 == (NR+1) % 2' 对于“偶数”行 2,4,6,8 ls |awk '0 == ( NR) % 2'
为了更完整..
ls -l | (for ((x=0;x<2;x++)) ; do read ; done ; head -n1)
丢弃行,直到到达第二行,然后打印出第一行。所以,它打印第三行。
如果只是第二行..
ls -l | (read; head -n1)
根据需要放置尽可能多的“阅读”。
不定期副业成功案例分享
p
是sed
语句,它打印由其前面的行范围标识的行。因此2,4p
表示打印第 2、3、4 行。n
表示不打印所有其他行