
wc -l
ファイル内に存在する行数を確認するために使用しています。 いつもは問題なく動作していたのですが、今回はうまくいきませんでした。
それぞれ少なくとも 2 行あるはずの 120 個の大きなファイルがあります。これらのファイルに対してテキスト編集作業を行って、行を削除したり、新しい行を追加したりしました。wc -l *
通常どおりを使用して最終的な行数を確認しようとしました。出力によると、ほとんどのファイルには 1 行しかありませんでした。
ファイルの 1 つ (コマンドの結果から 1 行しかないことが示されました) を で開くと、vim
ちょうど 2 行あることがわかります。 を終了しvim
、 を使用して再度確認するとwc -l
、そのファイルの行数は 2 と表示されました。
ここで何が起こったのか誰か分かるでしょうか? また、120 個のファイルすべてを で開く代わりに、この問題を解決するにはどうすればいいでしょうかvim
?
PS: ファイルの最後の行は空ではありませんでした。
答え1
の一般的なGNU実装はwc
言う
'wc' は、指定された各 FILE 内のバイト数、文字数、空白で区切られた単語数、
および改行数をカウントします。FILE が指定されていない場合や '-' の FILE の場合は標準入力内のバイト数をカウントします。
したがって、ファイルの最後の改行文字がない場合、wc
出力の「行」部分は予想よりも1つ少なくなります。たとえば、次の出力は1になります。
printf 'hello\nworld' | wc -l
OPはコメントで、vimが最後の改行がないことを報告していることを確認しました。すべてのファイルにこの問題があることがわかっている場合の簡単な修正方法は、
for f in *
do
echo >> "$f"
done
各ファイルに改行を追加します。
すべてのファイルの末尾に改行が欠落している場合に条件付きで改行を追加するには、sed を使用します。
sed -s -i '$s/$/\n/;P;d' *
-s
各ファイルを個別に処理し、-i
インプレース編集を行い、改行を表現できるようにするために、いくつかの GNU 拡張機能を使用します\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 を使用) 改行なしスペースを正規化します。
必ずテキスト ファイルのみに使用してください。