【发布时间】:2014-12-11 16:14:40
【问题描述】:
我想跟踪操作多个文件的 awk 命令的进度。目前,我正在使用每个打印语句将文件名打印到屏幕上,但我宁愿不要淹没屏幕。我不是每次都打印到新行,而是希望一遍又一遍地写到同一行。这可能吗?
【问题讨论】:
-
如果您提供更多上下文,准确解释您正在尝试做什么并显示您的脚本,这将很有用。可能还有其他方法可以解决这个问题。
我想跟踪操作多个文件的 awk 命令的进度。目前,我正在使用每个打印语句将文件名打印到屏幕上,但我宁愿不要淹没屏幕。我不是每次都打印到新行,而是希望一遍又一遍地写到同一行。这可能吗?
【问题讨论】:
我正在提交一个替代方案,它与接受的答案几乎相同,但巫毒教更少:
awk '{ printf("\r" $0) }'
\r 是“回车” - 在 Windows (MS-DOS) 中,它是用于表示新行 (CRLF) 的两个字符之一 - 在 Unix 中仅使用 \n (LF),并且\r 使用时仅表示将字符返回到当前行的开头。
所以这个例子只是重复输入,但每次都从同一行的开头开始(与 print 不同,printf 在 awk 中没有发出隐式换行符)。
因此,举个玩具例子,每秒在同一行更新时间:
while sleep 1; do date ; done | awk '{ printf("\r" $0) }'
我不能肯定,但也许这是一个更广泛兼容的解决方案,因为它不依赖于 ANSI 终端功能?也许终端对回车的支持无论如何都基于 ANSI 转义......我认为在退化的情况下,它会在屏幕上打印更少的 gobbledygook。
【讨论】:
您可以将ANSI Escape sequences 与awk 一起使用。试试这个:
seq 1 100000 | awk '{print $1 "\033[1A"}'
Esc[ValueA 光标向上:
将光标向上移动指定的行数而不更改列。如果光标已经在第一行,ANSI.SYS 会忽略这个序列。
要解决 Jlliagre 提出的问题,您可以这样做:
seq 100000 -1 1 | awk '{print "\033[2J\033[;H" $1}'
清除屏幕并将光标位置设置为0,0
【讨论】:
这是一种方法:
find / -type f 2>/dev/null | \
awk -v c=${COLUMNS:-80} '{ printf("%-*.*s \r",c-1,c-1,$0);}'
printf 命令正在截断显示的字符串以将输出保留在一行中,并被下一行覆盖。
如果您知道输出的最大宽度,则可以使用它来代替 COLUMN 变量。这将使这个过程更快。
【讨论】: