如何流式编辑类似进度的输出?

如何流式编辑类似进度的输出?

我在编辑某些进度输出时遇到问题。在本例中,它是 Postgres' pg_basebackup,但它与其他进度输出(如curl 和 wget)类似。以此为例:

generate_output() {
    for f in {1..500}; do 
        sleep 0.01
        echo -ne "Downloading... $f/500 foo   \\r"
    done
    echo -e "\nSome final line 1\nSome final line 2"
}

哪个有这样的输出

Downloading... 1/500 foo
(...same line...)
Downloading... 500/500 foo
Some final line 1
Some final line 2

我怎样才能从这个输出中删除“foo”,同时保持类似进度的性质?(而不是被缓冲,因此无用)

我已经尝试了两者awksed但两者似乎都严重依赖行缓冲,并且输出中没有换行符,Downloading...直到完全完成为止。

我得到的最接近的是一个 hack,它首先替换CRLF,然后再次替换它。但这搞砸了实际的换行符(例如“Some Final line 1”)

generate_output | stdbuf -i0 -o0 tr $'\r' $'\n' | sed -u -e 's/ foo//' | stdbuf -i0 -o0 tr $'\n' $'\r'

有没有办法配置awksed处理这个问题?或者有更好的工具来完成这项工作?

笔记:

  • 出于一般性目的,上述输出已被清理。实际输出是42318/42318 kB (100%), 1/1 tablespace, 我想修剪所有内容,包括逗号和逗号之后。
  • 我看到了一些有关 awk -W 交互式选项的建议,但我无法使用该选项。

答案1

这是一个珀尔一行将您的generate_output通过管道传输到:

perl -e '$/ = "\r"; $| = 1; while(<STDIN>){s/ foo//;print;}'

$/设置输入行分隔符,并使$|输出不缓冲。

答案2

这是一个巴什将您的管道generate_output输送到的解决方案:

#!/bin/bash
while read -d $'\r' line
do      echo -ne "${line% foo}\r"
done
echo "$line"

相关内容