次のbashスクリプトは、1..1000の高い数の範囲で動作します。
カウント範囲が1..1000000より高いため、起動に時間がかかります。全体的にうまくいきます。
for i in {1..10}; do
printf '\r%2d' $i
sleep 1
done
printf '\n'
99..1から始まる数値範囲の逆数に対してはうまく機能します。
99以降で始まる数値範囲をカウントダウンするために、pe 100..1出力はゼロを含む数値を印刷しすぎます。これをどのように避けることができますか?
答え1
あなたの質問:
コマンドの開始には時間がかかります。これは、ループに使用した支柱の拡張によるものです。拡張は最初に行わなければなりません。拡大するこれは、シェルが繰り返す範囲のすべての数字を含むリストを生成する必要があることを意味します。これには時間(リストの作成)とメモリ(リストの保存)が必要です。私のコンピュータで
bash
プロセスが成長していることがわかります。約1400KiBから256MiBまで私がリストを生成するように要求したとき{1..1000000}
。代わりに、算術ループを使用することを検討してください。
for (( i=1000000; i >= 1; --i )); do ...; done
またはPOSIX互換ループ、
i=1000000 while [ "$i" -ge 1 ]; do ...; i=$(( i - 1 )); done
どちらの方法も静的数値リストを繰り返さず、代わりにテスト値に基づいてループ本体を実行し、テストが成功すると
$i
各反復で変数値を減らします。1
i
各数字の末尾には「追加0」があります。これは、キャリッジリターン文字を出力してカーソルを行の先頭に戻すためです。カーソルは移動しますが、行は消去されないため、新しい数字の桁数が少なくても、最後の出力数字の終わりは引き続き表示されます。
この問題を解決するには、次を試してください。VT100エスケープコード
\e[2K
カーソルを行の先頭()に移動する前に、行全体を消去するために使用されます。for (( i=1000000; i >= 1; --i )); do printf '\e[2K\r%d' "$i" sleep 1 done printf '\n'
\e[1K
カーソルの左側の行領域を消去するかのように機能します。または\r%d\e[0K
明確な線を使用してください正しい数値出力後のカーソルの位置です。
答え2
あなたが見る問題は、最初に書いて100
から同じ場所から始まりますが、出力形式に2桁しか指定しないということ99
です。1
%2d
消去手順を提供していないので、これが表示されます。しかし、すべてが一行にあります。
What # What
you # was
see # output
100 # 100
990 # 99
980 # 98
...
90 # 9
80 # 8
...
10 # 1
3桁の数字で書式設定するか、空白のサフィックスを追加する必要があります。
printf "\r%3d" $i # One option
printf "\r%2d " $i # Another option
答え3
ある文字列を別の文字列に置き換えるには、両方の文字列が同じサイズ(または印刷できない文字(スペース?)が長くなければならない)が必要です。
123
印刷内容をに置き換えると、最初に印刷するのか、最後に印刷するのかに応じて、またはが7
得られます。723
127
これを行うには(同じサイズの文字列)、次のいずれかを実行できます。
- 安定したサイズの支柱拡張を使用してください。
{000..123}
- スペース全体を埋めるには、printf を使用します。
printf '\r%5s' "$i"
- 長い空白文字列を印刷します。
printf '\r%s ' "$i"
- 行が終わるまで行を消去します。
printf '\r%s\e[K' "$i"
- 行全体を消去して値を印刷します。
printf '\e[2K\r%s' "$i"
ただし、{1..1000000}を使用することは、メモリに保存して空白で割ってループで使用する必要がある長い数値文字列を生成するため、これは最善の解決策ではありません。 Bashのより良い解決策は次のとおりです。
for(( i=1; i<1000; i++ )); do
printf '\r%5d' $i
sleep 0.01
done
echo