コマンドによって出力された行数をリアルタイムで表示する方法は?


15

私はsvn export自分のアプリケーションのパッケージャースクリプトの一部として使用していますが、このコマンドは、他の多くのコマンドと同様、プログレスバーを備えていないようです。

現時点では2つの選択肢があります。

  • オプションなしで使用し、数千行を印刷するのを見る
  • を使用し--quiet、完了するまで何もしません。

少なくともコマンドによって出力された行数をリアルタイムで表示する方法はありますか?といった:

Exporting SVN directory ... 1234 files

そして、この数1234 がリアルタイムで増加するのを見てください。これを行うコマンドに出力をパイピングすることを想像できますが、どれですか?

回答:


16
yourcommand | { I=0; while read; do printf "$((++I))\r"; done; echo ""; }

または、括弧で囲まれたセクションをシェルスクリプトに入れます。これは、bash、ksh93、zshなど、シェルが実際にプリインクリメント演算子をサポートしている場合にのみ機能することに注意してください。それ以外の場合は、増分$Iしてから印刷する必要があります(のようにI=$((I+1));printf...)。また、printfシェルのビルトインでない場合(現在のbashのビルトインである場合)、パフォーマンスを向上させるためにecho -neまたはをprint -n代わりに使用できます。改行を抑制し、\ rをエスケープ文字として解釈したいだけです。


ああ、私は自分自身にそのashい=点と `=`の違いと癖を付けてbashscriptingを学ばせることは決してないでしょう。:)彼らはなぜPythonの様syntaxed言語...と交換しません
ボリスBurkov

ねえ、私は知っている、何!印刷する新しい各行に復帰記号を追加できます。画面にあふれることはなく、前の行が上書きされます。
ボリスブルコフ

それがでprintf終わる理由\rです。そして、あなたがやるとどうなりますecho -ne "$I\r"print -n "$I\r"。:) printfしかし、デフォルトでは末尾に改行を印刷しないので\r、最初に戻ります。残念ながら、すべてのエコー実装が-eor -n引数をサポートしているわけではありません。
ダニーザウアー

1
これは、OpenBSDが/ bin / shに使用するpdkshバージョンでも機能します。
kurtm

1
+1ですが、絶対に正しいものに変更readする必要がありますread -r(そうしないと、行末のバックスラッシュがカウントを混乱させるため)。ちなみに、少し作業を行うと、最新の出力行も表示するように調整できます。これは、一部のコマンドに役立つ場合があります。
-ruakh

7

これは大まかな考えですが、pvコマンドを使用して行数をカウントし、画面に表示できます。 pv多くのスイッチの中には、-l通過する各行をカウントするスイッチがあります。

ここでは、SVN出力からいくつかのファイルをシミュレートするためにwhileループを使用しています。

$ for i in $(seq 100); do echo "file$i"; sleep 2; done | pv -l -c >/dev/null
   3 0:00:05 [0.99/s ] [      <=>             

次のように出力行を上書きし続けます。

  18 0:00:36 [   0/s ] [                                     <=>                                                                  ]

  24 0:00:47 [0.991/s ] [                                                <=>                                                      ]

私はPVを知りませんでした。ものを学ぶためのHooray!
ダニーザウアー

@dannysauer-pvは学習に時間を費やす価値があります。パイプを通過するものはすべて測定して表示できます。
slm

コメントを読んで遊んだ後、インストールしました。Linuxを使用して18年が経ちましたが、まだ新しい発見が常にあります。:)
ダニーザウアー

0

バックグラウンドでコマンドをジョブとして実行し、そのstdout(およびオプションでstderr)をログファイルにリダイレクトできます。command > logfile &ここで、&ジョブを指定します(stderrの場合、たとえばの&>代わりに>)。

次に、wordcountユーティリティを使用して、でログファイルの行数をカウントできますwc -l

動的に変化する1行で状態の変化を表示するには、のようなものを使用できますがwhile true; do echo -en '\r'; wc -l logfile; sleep 1; done、bashに強制的に\rキャリッジリターンを描画させて前の行の内容を強制終了することはできません。

この質問を参照してください、それはほぼ重複しています:https : //stackoverflow.com/questions/2388090/how-to-delete-and-replace-last-line-in-the-terminal-using-bash


1
しかし、彼は増分を続けるリアルタイム表示を望んでいますが、これはwcが行うことではありません。
kurtm

@kurtmええ、彼がもっと望んでprintf/print/echoいるのは、ダニーが示唆する結果で画面があふれないようにすることです。:)もちろん、彼はを使用できますがlesswc -l logfile彼はせっかちになるたびに言う余裕があると思います。ncursesここでは、画面で遊んだり画面をクリアしたりするのはやり過ぎだと思います。
ボリスブルコフ

はい、そうです。彼はそれが殺到することを望まないが、彼は進歩を知りたい、そうでなければ彼はただ--quietを使うことができる。
kurtm

@kurtmアップデートを参照してください:echo -e 'r'コマンドのデバッグを手伝ってもらえますか?以前に印刷された行の内容を消去して動的に変更する必要がありますが、それを強制することはできません:(
ボリスバーコフ

また、n行オプションをechoに追加して、末尾の改行を抑制します。
kurtm
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.