検索中のファイルのダウンロードの進行状況を抽出しようとしていますcurl
。
私はこれを試しましたが、うまくいきません。
curl --progress-bar http://127.0.0.1/test.tar.bz2 -o test.tar.bz2 2>/dev/stdout | sed -r 's/[# ]//g;s/^/#/g'
しかし、このsed
表現は大丈夫だと思います:
$ echo '######## 10.2%' | sed -r 's/[# ]//g;s/^/#/g'
#10.2%
誰もが私が間違っていることを指摘できますか?
答え1
主な質問はsed
次に適用されることです。ワイヤーしたがって、最初のコマンドに到達するまで何も実行せず、\n
コマンドが完了するまで何も起こりません。\r
sをsに置き換えることでこの問題を解決できます\n
。
$ curl --progress-bar http://127.0.0.1/test.tar.bz2 -o test.tar.bz2 2>&1 |
tr $'\r' $'\n' | sed -r 's/[# ]+/#/g;'
ただし、これによりバッファリングが提供され、複数の行sed
セットで機能します。私が一緒にハックした最後の解決策は、エラーをファイルにリダイレクトしてからそのファイルを処理することでした。
$ curl --progress-bar http://127.0.0.1/test.tar.bz2 -o test.tar.bz2 2>er
$ while :; do
echo -ne "$(tr $'\r' $'\n' < er | tail -n 1 | sed -r 's/^[# ]+/#/;')\r";
done
上記のコマンドは、エラーファイル(er
)を解析し、結果を印刷し、更新されたまま\r
にします。手動で削除する必要があります。
匿名ユーザーの提案:また、これらのコマンドstdbuf -oL
を先行して、そのコマンドのバッファリング動作を変更することもできます。tr
sed
答え2
Perlを試してみてください:
curl --progress-bar http://127.0.0.1/test.tar.bz2 -o test.tar.bz2 2>&1 | perl -015 -n -e 'print "$1\n" if (/[#]* ([\d]+)/);'
どこ:
- 2>&1 stdoutがある場所にstderrを割り当てます。この場合、perlのパイプです。
- -015入力レコード区切り文字をキャリッジリターン文字(8進数15)に設定します。
- -e は、この場合、先頭 # をスキップし、次の整数を $1 に抽出し、抽出が成功するたびに $1 を印刷するコード行です。
- -n は、"while(<>){}" で -e によって提供された行をラップし、EOF までレコードごとに入力レコードを読み取ります。ここで、各レコードはCRと-0で区切られるようにソートされます。