まず、この問題の背景を紹介します。while IFS= read -r line; do ... done < input.txt
よく知られている構造です。ファイルを1行ずつ読み込むシェルスクリプトから。しかし、Cスタイルのforループで作業している間(ここでいくつかのユーザーが知らない場合やfor((i=0;i<=$val;i++))do;...done
使用されているタイプです)、Cと同様の言語のwhileとforループは交換可能であり、他のループをシミュレートできることを覚えていました。 。それで、上記の構造をシミュレートするためにCスタイルのループを考えました。bash
ksh
while IFS= read -r line
for((i=1;;i++))
do
IFS= read -r line || break
# do something with line here
done < input.txt
\n
さまざまな種類の入力(通常の行、前のタブ/スペースのある行、終了しない行(最後の行をキャプチャできない場合))でテストしてみましたが、すべての場合に機能します。どちらも完全に有効でread
ループ方式と同じですwhile
。技術的には、変数には「組み込み」行カウンタもありますi
。
したがって、質問にこのアプローチを使用しない理由はありますか(PythonとPythonを除く他のシェルに移植できないことに加えてksh
)?bash
可能な失敗はありますか?このアプローチはうまく機能しますが、私のスクリプトでこのアプローチを積極的に使用する前に私が見落としている問題があるかどうかを知りたいです。
ベストアンサー1
このアプローチを使用しない理由はありますか?
明確さまたは不足。
while
このようなループは次のようにwhile sometest ; do ...
書くこともできます。
while :; do
if ! sometest; then
break
fi
...
しかし、私たちは(シェルやCで)これをしません。なぜなら、ループ条件を人々が見つけるのに慣れている場所から遠ざかるからです。構成は似ています。構成の中間式を空白のままにしますfor (( ; ; ))
。
もちろん、for (( ; ; ))
シェルは算術式のみを評価するので、これを行う必要がありますread
。for
とwhile
Cでは簡単に変換できますが、同じ状況がシェルには適用されません。
(Cでもfor
ループの構造は計算ループを意味すると言いたいのですが、もちろん完全には明確ではありません。)
これに関しては:
技術的には、i変数を含む「組み込み」行カウンタもあります。
私はそれに組み込まれたものは何もないと思います。行カウンタを手動で初期化し、手動でインクリメントしました。より伝統的なループを使用してwhile
同じことを行うことができます。
i=0
while IFS= read -r line; do
...
let i++
done < input.txt
(またはi=$((i + 1))
より携帯可能)