/tmp/urlFile
各行がURLを表すというファイルがあります。次のファイルを読み取ろうとします。
cat "/tmp/urlFile" | while read url
do
echo $url
done
最後の行が改行文字で終わらない場合、その行は読み取られません。理由を知りたいです。
新しい行で終わるかどうかに関係なく、すべての行を読み取ることができますか?
答え1
あなたはこれを行います:
while IFS= read -r url || [ -n "$url" ]; do
printf '%s\n' "$url"
done < url.list
(実際には、ループは最後の(非)行に欠落している改行文字を追加します)。
また見なさい:
答え2
さて、read
改行の前にファイルの終わりを見つけた場合は偽の値を返しますが、それでも読み取った値を割り当てます。したがって、最終呼び出しが空行以外のread
ものを返すことを確認し、正常に処理できます。したがって、read
falseを返した後にのみループを終了してください。そして行が空です。
#!/bin/sh
while IFS= read -r line || [ "$line" ]; do
echo "line: $line"
done
$ printf 'foo\nbar' | sh ./read.sh
line: foo
line: bar
$ printf 'foo\nbar\n' | sh ./read.sh
line: foo
line: bar
答え3
渡す定義、テキストファイルは一連の行で構成されます。 ㅏワイヤー改行文字で終わります。したがって、テキストファイルは空でない場合は改行文字で終わります。
組み込みread
機能は、テキストファイルを読み取る目的でのみ使用されます。テキストファイルを渡さないので、スムーズに動作することは期待できません。シェルはすべての行を読みます - スキップは最後の行の後の追加の文字です。
間違った形式の入力ファイルがある場合(最後の行が欠落している可能性がある)、確実に確認するために改行を追加できます。
{ cat "/tmp/urlFile"; echo; } | …
テキストファイルでなければなりませんが、最後の改行文字が欠落しているファイルは通常Windowsエディタで作成されます。これは通常、Unix の LF ではなく Windows 行終端者 CR LF で使用されます。 CR文字はどこでもほとんど役に立たず、どのような状況でもURLに表示してはいけませんので、削除する必要があります。
{ <"/tmp/urlFile" tr -d '\r'; echo; } | …
入力ファイルの形式が正しく、改行で終わる場合は空echo
行が追加されます。 URLは空白にできないため、空白行を無視してください。
また、read
直接的な方法で行を読み取らないことに注意してください。 URLに最適な先行スペースと末尾のスペースを無視します。行末のバックスラッシュをエスケープ文字として処理し、次の行が最初の行からバックスラッシュの改行シーケンスを引いたものに関連付けるようにします。これは絶対に望ましくありません。したがって、-r
オプションをに渡す必要がありますread
。これは非常にまれで、read
正しいことではありませんread -r
。
{ <"/tmp/urlFile" tr -d '\r'; echo; } | while read -r url
do
if [ -z "$url" ]; then continue; fi
…
done
答え4
別の方法は次のとおりです。
読み込みが行末ではなくファイルの終わりに達すると、データを読み込み変数に割り当てますが、ゼロ以外の状態で終了します。ループが「読み込み中、タスクを実行し、完了中」に構成されている場合
したがって、読み取り終了ステータスを直接テストするのではなく、フラグをテストし、読み取りコマンドがループ本体内でそのフラグを設定するようにします。これにより、読み取りの終了状態に関係なく、ループ全体の本文が実行されます。なぜなら、読み出しはループ内のコマンドのリストの1つに過ぎず、他のコマンドと同様にループを実行するかどうかを決定する要素がまったくないからです。
DONE=false
until $DONE ;do
read || DONE=true
echo $REPLY
done < /tmp/urlFile
おすすめの人ここ。