
Ich habe es verwendet, wc -l
um zu prüfen, wie viele Zeilen in meinen Dateien vorhanden sind. Es hat immer gut funktioniert, aber dieses Mal nicht.
Ich habe 120 große Dateien, die jeweils mindestens zwei Zeilen enthalten sollten. Ich habe gerade einige Textbearbeitungsarbeiten an diesen Dateien durchgeführt, um Zeilen zu entfernen und neue hinzuzufügen. Ich habe versucht, die endgültige Zeilenanzahl wie gewohnt zu überprüfen wc -l *
. Die Ausgabe zeigte, dass die meisten Dateien nur eine Zeile hatten.
Ich habe eine der Dateien (die laut Befehlsergebnis nur eine Zeile hatte) mit geöffnet vim
und kann sehen, dass sie genau 2 Zeilen hatte. Beenden Sie vim
und überprüfen Sie sie erneut mit wc -l
, die Zeilenanzahl für diese Datei wurde dann als 2 angezeigt.
Hat jemand eine Idee, was hier passiert ist? Und wie kann ich dieses Problem lösen, anstatt alle 120 Dateien mit zu öffnen vim
?
PS: Die letzte Zeile meiner Dateien war nicht leer.
Antwort1
Die allgemeine GNU-Implementierung von wc
says
„wc“ zählt die Anzahl der Bytes, Zeichen, durch Leerzeichen getrennten Wörter
und Zeilenumbrüche in jeder angegebenen DATEI oder in der Standardeingabe, wenn keine angegeben sind oder für eine DATEI mit „-“.
Wenn also kein abschließendes Zeilenumbruchzeichen in der Datei vorhanden ist, wc
wird der "Zeilen"-Teil der Ausgabe um eins kleiner sein als erwartet. Im Folgenden wird beispielsweise 1 ausgegeben.
printf 'hello\nworld' | wc -l
Der OP hat in Kommentaren bestätigt, dass vim das Fehlen der letzten Newline meldet. Eine einfache Lösung, wenn bekannt ist, dass alle Dateien dieses Problem haben, ist
for f in *
do
echo >> "$f"
done
um jeder Datei eine neue Zeile anzuhängen.
Eine Möglichkeit, am Ende aller Dateien bedingt eine neue Zeile hinzuzufügen, wenn eine fehlt, ist die Verwendung von sed.
sed -s -i '$s/$/\n/;P;d' *
verwendet einige GNU-Erweiterungen, -s
um jede Datei separat zu behandeln, -i
eine Bearbeitung direkt vor Ort durchzuführen und die \n
Darstellung einer neuen Zeile zu ermöglichen. Das sed-Programm selbst sagt, dass in der letzten Zeile jeder Datei eine neue Zeile angehängt werden soll, und druckt für jede Zeile bis zur ersten neuen Zeile und fährt mit der nächsten Zeile fort.
Antwort2
Dies ist nicht direkt eine Antwort, sondern ich teile ein kleines persönliches Tool, das ich oft verwende, um Textdateien (txtnorm) zu normalisieren:
#!/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
normalisiert das Zeilenende, stellt neue Zeilen am Ende des Zeilenumbruchs sicher, entfernt BOMs und normalisiert (mit -s) ggf. geschützte Leerzeichen.
Verwenden Sie es NUR für Textdateien.