我可以用awk覆盖屏幕上的输出吗?
Can I overwrite output to the screen with awk?
问题的出现原因:
在awk命令中,使用printf命令来输出字符串。而在这个例子中,printf命令将字符串截断以使输出保持在一行,并在下一行输出时覆盖上一行。这样做的目的是实现输出内容的更新和覆盖,以达到显示动态信息的效果。
解决方法:
如果你知道输出的最大宽度,可以使用它来替代COLUMNS变量。这样做可以提高处理速度。
以下是一种实现方式:
find / -type f 2>/dev/null | \ awk -v c=${COLUMNS:-80} '{ printf("%-*.*s \r",c-1,c-1,$0);}'
在这个例子中,通过find命令找到文件列表,并通过管道传递给awk命令。awk命令中的printf语句使用变量c来指定输出的最大宽度。printf语句的格式为"%-*.*s \r",其中*用于指定宽度,$0表示输出的字符串。通过\r实现覆盖输出的效果。
这样,就可以使用awk命令覆盖屏幕上的输出了。
原因:这个问题的出现是因为在awk命令中,想要覆盖输出到屏幕的内容。
解决方法:可以使用awk的printf函数和\r(回车符)来实现覆盖输出。在Windows中,\r是用来表示换行符(CRLF)的两个字符之一;而在Unix中,只使用\n(LF)来表示换行,\r则表示将光标返回到当前行的开头。因此,可以通过在awk中使用printf函数来实现在同一行上重复输出。
例如,以下是一个简单的示例,每秒更新同一行上的时间:
while sleep 1; do date; done | awk '{ printf("\r" $0) }'
虽然无法确定,但这种方法可能更加兼容,因为它不依赖于ANSI终端特性。也许终端对回车符的支持本身就是基于ANSI转义的...不过在极端情况下,这种方法可能会在屏幕上打印出较少的乱码。
在awk中,可以使用ANSI转义序列控制屏幕的输出。下面是一种方法:
seq 1 100000 | awk '{print $1 "\033[1A"}'
这个命令会将光标向上移动一行,并在当前位置打印数字。其中`\033[1A`是ANSI转义序列,表示向上移动一行。
另外,为了解决Jlliagre提出的问题,可以使用以下命令:
seq 100000 -1 1 | awk '{print "\033[2J\033[;H" $1}'
这个命令会清空屏幕,并将光标位置设置为0,0。
这种方法有两个问题。如果要显示的字符串宽度超过终端宽度,多余的行会留在屏幕上。如果要显示的字符串比之前的字符串短(例如:`time seq 100000 -1 1`),之前的字符会在其后显示出来。
有人问为什么要将转义字符导入文件中。实际上,这只是为了控制屏幕的输出。
awk可以使用ANSI转义序列控制屏幕的输出。使用`\033[1A`可以将光标向上移动一行,使用`\033[2J\033[;H`可以清空屏幕并将光标位置设置为0,0。然而,这种方法在处理超过终端宽度的字符串或者之前字符串比较长的情况下会出现问题。