8

readファイルの最後に「改行」文字がない場合、ファイルの最後の行を実際に読み取ることはないことにしばらく気づきました。これは、ファイルに「改行」文字がない限り、0行が含まれているように見えることを考えると理解できます(これは認めるのが非常に難しいです!)。たとえば、次を参照してください。

$ echo 'foo' > bar ; wc -l bar
1 bar

だが...

$ echo -n 'bar' > foo ; wc -l foo
0 foo

read問題は、自分で作成または変更されていないファイルを処理するために使用するときに、実際に「改行」文字で終わるかどうかわからないような状況をどのように処理できるかということです。

4

4 に答える 4

15

read実際、終了していない行を割り当てられた変数に読み込みます($REPLYデフォルト)。また、そのような行ではfalseを返します。これは、「ファイルの終わり」を意味します。したがって、クラシックループで戻り値を直接使用すると、while最後の1行がスキップされます。ループロジックを少し変更すると、事前のサニタイズを必要とせずに、改行されていない行末のファイルを正しく処理できますread

while read -r || [[ -n "$REPLY" ]]; do
    # your processing of $REPLY here
done < "/path/to/file"

これは、外部に依存するソリューションよりもはるかに高速であることに注意してください。

ループロジックを改善するためのGordonDavissonへのヒント。

于 2013-01-27T12:19:35.977 に答える
2

POSIXでは、ファイル内のすべての行の末尾に、それが行であることを示す改行文字が必要です。しかし、このサイトは、あなたが説明しているシナリオを正確に解決するソリューションを提供します。最終製品はこのチャンクレットです。

newline='
'
lastline=$(tail -n 1 file; echo x); lastline=${lastline%x}
[ "${lastline#"${lastline%?}"}" != "$newline" ] && echo >> file
# Now file is sane; do our normal processing here...
于 2013-01-27T05:16:12.330 に答える
1

readを使用する必要がある場合は、次のことを試してください。

awk '{ print $0}' foo | while read line; do
    echo the line is $line
done

awkは改行文字がなくても行を認識しているようです

于 2013-01-27T05:22:48.867 に答える
1

これは多かれ少なかれこれまでに与えられた答えの組み合わせです。

所定の場所にあるファイルは変更されません。

(cat file; tail -c1 file | grep -qx . && echo) | while read line
do
    ...
done
于 2013-01-27T10:32:55.353 に答える