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非常小的输出。