wc コマンドがファイル行番号を読み取る際にエラーが発生しました。

wc コマンドがファイル行番号を読み取る際にエラーが発生しました。

wc -lファイルに存在する行数を確認しています。いつもうまくいきましたが、今回はそうではありませんでした。

120個の大きなファイルがあり、各ファイルには少なくとも2行が必要です。私はこのファイルに対してテキスト編集を実行し、新しい行を削除して追加しました。wc -l *通常どおりに使用して最終行数を確認しようとしています。出力には、ほとんどのファイルに1行しかないと表示されます。

ファイルの1つを開きましたが(コマンド結果には1行しかありませんでした)、vim正確に2行があることがわかりました。終了し、次を使用してvimもう一度確認してください。wc -l

ここで何が起こっているのか知っている人はいますか? 120個のファイルをすべて開くことなく、この問題をどのように解決できますかvim

PS:私のファイルの最後の行は空ではありません。

答え1

一般的なGnuの実装はwc次のとおりです。


'wc'指定された各FILEまたは標準入力(何も指定されていない場合、またはFILEが '-'の場合)で、バイト、文字、スペースで区切られた単語、および改行の数を数えます。

したがって、ファイルに最後の改行文字がない場合、出力の「行」部分はwc予想より1小さくなります。たとえば、次は1を出力します。

printf 'hello\nworld' | wc -l 

OPはvimが最終改行が欠落していると報告したというコメントを確認しました。すべてのファイルにこの問題があることがわかっている場合、簡単な修正方法は次のとおりです。

 for f in *
 do
     echo >> "$f"
 done

各ファイルに改行を追加します。

すべてのファイルに改行がない場合は、ファイルの末尾に条件付きで改行を追加する1つの方法はsedを使用することです。

sed -s -i '$s/$/\n/;P;d' *

一部のGNU拡張機能を使用して、-s各ファイルを個別に処理し、-i内部編集を許可し、改行文字を表示すること\nができます。 sedプログラム自体は、各ファイルの最後の行に改行文字を追加し、各行の最初の改行文字まで印刷し、次の行に移動することを意味します。

答え2

これは正確な答えではありませんが、テキストファイルを正規化するためによく使用される小さな個人用ツール(txtnorm)を共有します。

#!/usr/bin/perl -spi
our($s);
s/\n\r|\r\n|\n|\r/\n/g;                 ## normalize \n
s/^(\xFF\xFE|\xFE\xFF|\xEF\xBB\xBF)//;  ## remove BOM !
s/(?<=.)\z/\n/;                         ## ensure newline at eof

if($s){ s/\xC2\xA0/ /g }                ## -s non breaking spaces-> " "

txtnorm *.txt行末を正規化し、eofで改行を保証し、BOMを削除し、-sを使用して切り捨て防止スペースを正規化できます。

必ずテキストファイルにのみ使用してください。

関連情報