【问题标题】:AWK print a CR before line numberAWK 在行号之前打印一个 CR
【发布时间】:2018-04-08 02:15:47
【问题描述】:

我做了一个命令来动态显示tar处理了多少文件:

tar zcvf some_archive.tar.gz /a/lot/of/files | \
awk 'ORS="\r"{print NR} END{print "\n"}'

通过这种方式,我可以看到越来越多的数字,因为tar 为每个处理的文件输出一行。

但是,光标始终位于第一位数字下方。我希望它在最后一个数字之后,所以我有这个:

awk 'ORS=""{print "\r"NR} END{print "\n"}'

遗憾的是,AWK 停止动态生成任何输出。

那我该怎么做呢?

【问题讨论】:

  • ITYM BEGIN{ORS="whatever"}。正如所写的那样,您的脚本将为每个输入行设置 ORS,然后只执行结果非零和非空的相关操作,因此例如,您的第二个脚本将只输出一个换行符。

标签: awk


【解决方案1】:

不知道为什么,但更改为 printf 对我有用(而且您也不需要设置 ORS):

for i in {1..20}; do echo x; sleep 1; done | awk '{printf "\r" NR} END {print ""}'

这可能是一个比较满意的答案,加个flush强制输出:

 for i in {1..20}; do echo x; sleep 1; done | awk -v ORS="" '{print "\r" NR; fflush()} END {print "\n"}'

【讨论】:

  • OPs 2nd 脚本不会输出任何东西(请参阅我在它下面的评论)和(除了缺少的BEGIN{})你的工作但 OPs 第一个不是@987654324 的原因@ 将光标返回到行首,所以当 ORS="\r" 像 OP 一样时,光标在每次打印 NR 后立即返回到开头,所以看起来它永远不会离开那个位置,而你的光标返回到在打印 NR 之前行的开头,因此它会一直留在那里,直到处理下一个输入行。
  • 谢谢,一如既往,@EdMorton,我仍然不明白为什么我的 printf 版本不需要刷新,而打印版本需要。打印版本需要刷新我并不感到惊讶,因为通常需要换行符才能将缓冲区的内容推送到标准输出,但使用 printf 我似乎既不需要换行符也不需要刷新。
  • print 受 ORS 值的影响,所以我怀疑你看到的是一种优化,当 ORS 为空时不从 print 执行 I/O 直到如果/当存在换行符时,而 printf始终不受 ORS 值的影响,并且假定您在使用它时想要完全控制。
猜你喜欢
  • 1970-01-01
  • 2014-04-12
  • 2022-09-23
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多