しばらく前にファイルから入力を読み取るコードを見つけましたが、Stack Exchangeを介して自分のニーズに合わせて調整できたと思います。
while read -r line || [[ -n "$line" ]]; do
if [[ $line != "" ]]
then
((x++))
echo "$x: $line"
# <then do something with $line>
fi
done < "$1"
今私のスクリプトを見直し、それが何をしているのか理解しようとしています。この文が何をしているのかわかりません。
while read -r line || [[ -n "$line" ]];
私はその-r
オプションが私たちが生のテキストを読んでいることを意味していることを知っていますが、$line
文の対応する部分については混乱しています。|| [[ -n "$line" ]]
誰かがこれが何をしているのかを説明できますか?
ベストアンサー1
[[ -n "$line" ]]
$line
(読んだばかりの変数)が空でないことをテストしますread
。read
次の場合は成功を返すので便利です。〜しない限りそれを見る改行文字ファイルが終了する前に。入力に末尾に改行文字のない行の断片が含まれている場合、このテストはその行をキャプチャし、ループは最後の不完全な行も処理します。追加のテストがなければ、不完全な行を読み取ることができますが、$line
ループでは無視されます。
POSIXが定義しているので、「不完全な行」と言います。テキストファイルそして一行各行の末尾に改行文字が必要です。他のツールread
も管理できます。wc -l
改行文字の数を計算します。したがって、最後の不完全な行は無視されます。たとえば、参照してください。ファイルの最後に新しい行を追加するのはなぜですか?そしてテキストファイルが改行で終わるのはなぜですか?それはすべてです。
もちろん、このcmd1 || cmd2
構造はCの同等の構造に似ています。最初のコマンドがエラー状態を返すと、2番目のコマンドが実行され、結果は最後に実行されたコマンドの終了ステータスです。
比較する:
$ printf 'foo\nbar' | ( while read line; do
echo "in loop: $line"
done
echo "finally: $line"
)
in loop: foo
finally: bar
そして
$ printf 'foo\nbar' | ( while read line || [[ -n $line ]]; do
echo "in loop: $line"
done
echo "finally: $line"
)
in loop: foo
in loop: bar
finally: