
我一直wc -l
在檢查文件中存在的行數。它一直工作得很好,但這次不行。
我有 120 個大文件,每個文件應該至少有兩行。我剛剛對這些文件進行了一些文字編輯工作,以刪除和添加新行。我試圖wc -l *
像往常一樣使用來檢查最終的行數。輸出顯示大多數文件只有一行。
我打開了其中一個文件(從命令結果顯示它只有一行),vim
我可以看到它正好有 2 行。退出vim
並使用 再次檢查wc -l
,該檔案的行數顯示為 2。
有人知道這裡發生了什麼事嗎?我怎麼能解決這個問題而不是用打開所有 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
向每個文件附加換行符。
如果所有檔案缺少換行符,有條件地在其末尾添加換行符的一種方法是使用 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)可以標準化不間斷空格。
請務必僅在文字檔案上使用它。