我在编辑某些进度输出时遇到问题。在本例中,它是 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”,同时保持类似进度的性质?(而不是被缓冲,因此无用)
我已经尝试了两者awk
,sed
但两者似乎都严重依赖行缓冲,并且输出中没有换行符,Downloading...
直到完全完成为止。
我得到的最接近的是一个 hack,它首先替换CR
为LF
,然后再次替换它。但这搞砸了实际的换行符(例如“Some Final line 1”)
generate_output | stdbuf -i0 -o0 tr $'\r' $'\n' | sed -u -e 's/ foo//' | stdbuf -i0 -o0 tr $'\n' $'\r'
有没有办法配置awk
或sed
处理这个问题?或者有更好的工具来完成这项工作?
笔记:
- 出于一般性目的,上述输出已被清理。实际输出是
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"