【问题标题】:Can I overwrite output to the screen with awk?我可以用 awk 覆盖屏幕的输出吗?
【发布时间】:2014-12-11 16:14:40
【问题描述】:

我想跟踪操作多个文件的 awk 命令的进度。目前,我正在使用每个打印语句将文件名打印到屏幕上,但我宁愿不要淹没屏幕。我不是每次都打印到新行,而是希望一遍又一遍地写到同一行。这可能吗?

【问题讨论】:

  • 如果您提供更多上下文,准确解释您正在尝试做什么并显示您的脚本,这将很有用。可能还有其他方法可以解决这个问题。

标签: bash awk


【解决方案1】:

我正在提交一个替代方案,它与接受的答案几乎相同,但巫毒教更少:

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。

【讨论】:

    【解决方案2】:

    您可以将ANSI Escape sequencesawk 一起使用。试试这个:

    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

    【讨论】:

    • 好一个! (之前赞成)。相关阅读:Clear the Ubuntu bash screen for real
    • 这种方法有两个问题。如果要显示的字符串比终端宽度宽,额外的行将留在屏幕上。如果要显示的字符串比前一个字符串短(例如:time seq 100000 -1 1),则在其后显示剩余字符。
    • 这确实是一种解决方法,其优点是不截断已处理的行。不过,清除屏幕可能是个问题。
    • 第二个命令出现了一个空白屏幕。对于第一个,将其通过管道传输到文件将为您提供带有控制字符的序列列表。为确保终端看到与文件相同的内容,重要的是不要依赖转义序列,而是预先格式化输出。
    • @joepd 为什么喜欢将转义字符通过管道传输到文件中?这只是为了控制输出到屏幕。
    【解决方案3】:

    这是一种方法:

    find / -type f 2>/dev/null | \
      awk -v c=${COLUMNS:-80} '{ printf("%-*.*s \r",c-1,c-1,$0);}'
    

    printf 命令正在截断显示的字符串以将输出保留在一行中,并被下一行覆盖。

    如果您知道输出的最大宽度,则可以使用它来代替 COLUMN 变量。这将使这个过程更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-07
      • 1970-01-01
      • 1970-01-01
      • 2013-09-26
      相关资源
      最近更新 更多