改行で終わらない行指向ファイルを読み込む

改行で終わらない行指向ファイルを読み込む

/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ものを返すことを確認し、正常に処理できます。したがって、readfalseを返した後にのみループを終了してください。そして行が空です。

#!/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

おすすめの人ここ

関連情報