Pee*_*aha 3 performance shell io wc
我wc -l
用来计算命令输出中的行数,因为输入是通过管道传输到它的。
commad | wc -l
Run Code Online (Sandbox Code Playgroud)
这工作正常,但如果command
正在进行一些繁重的计算,这很慢。是否有替代方法可以显示“到目前为止已通过管道输入”的行数?
当我在做一种每项计算时,这样的事情会特别有用,比如
cat something | xargs -L1 heavy-per-line-computation | wc -l
Run Code Online (Sandbox Code Playgroud)
我可以手动执行此操作的一种方法是将输出通过管道传输到文件 ( command > file
) 并定期对其进行cat file | wc -l
处理。但是一个单一的命令(它不重定向到文件,以避免浪费的 I/O),就是我所追求的。
awk '{print NR}'
Run Code Online (Sandbox Code Playgroud)
此命令为遇到的每一行打印一个新数字。如果最后一行是完整的,那么最后一个数字将与所说的一致wc -l
。如果最后一行不完整,那么awk
可能会计算它(在我的 Kubuntu GNUawk
中)但wc -l
不会(因为它确实计算换行符);所以可能会有偏差。
另一个差异是如果输入完全为空:wc -l
将打印0
,我们awk
将不打印任何内容。要使其打印0
使用此变体:
awk '{print NR} END {if (NR==0) print NR}'
Run Code Online (Sandbox Code Playgroud)
或者,您可能希望每个新数字都覆盖控制台同一行中的旧数字。然后这个:
awk '{printf "\r%s",NR} END {print "\r"NR}'
Run Code Online (Sandbox Code Playgroud)
例子: yes | head -n 76543 | awk '{printf "\r%s",NR} END {print "\r"NR}'
请注意,该命令会消耗其输入(tee
可能很方便)。出于监控目的,您可能对以下内容感兴趣:
awk '{print NR OFS $0}'
Run Code Online (Sandbox Code Playgroud)
其中(默认OFS
为空格)几乎就像cat -n
(如果您cat
支持-n
)。
pv -l
计数线,它可以在管道内使用。例子:
for i in 1 2 3 4 5; do date; sleep 1; done | pv -l | wc -l
Run Code Online (Sandbox Code Playgroud)
考虑pv -lb
非常小的输出。