Shell-Script

如何流式傳輸類似編輯進度的輸出?

  • October 6, 2015

我無法編輯一些進度輸出。在這種情況下,它是 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 互動選項的建議,但我無法使用這些建議。

這是一個perl單行程序,用於將您的 generate_output 輸入:

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

$/設置輸入行分隔符,$|並使輸出無緩衝。

這是一個bash解決方案,可以將您generate_output輸入:

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

引用自:https://unix.stackexchange.com/questions/234317