Wie kann man das "No newline at end of file" Warnung für ganz viele Dateien?
Habe ich eine riesige Anzahl von source-Dateien, die alle ohne einen Zeilenumbruch am Ende.
Wie kann ich automatisch ein Zeilenumbruch am Ende jeder von Ihnen?
Einige haben vielleicht schon einen Zeilenumbruch, so ist es sollte nur Hinzugefügt werden, wenn nötig.
Ich bin wahrscheinlich nicht auf der Suche nach code, per se, sondern nur etwas, was ich kann im Terminal ausführen, um fügen Sie die notwendigen Zeilenumbrüche (oder irgendeine Art von Programmier-oder Entwicklungswerkzeug).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Umgewandelt Norman Antwort auf eine split-one-liner für Komfort.
Ersetzen Sie * mit was auch immer-Datei-Muster, die Sie möchten, zB
*.c
Und anderen nur sagen, welche Dateien defekt sind:
*
mit$(find . -type f)
oder$(find <dirname> -type f -name <filepattern>)
Wenn Sie Zugang zu Unix-tools, die Sie ausführen können
diff
um herauszufinden, welche Dateien fehlen eine neue Zeile und fügen Sie es:Ich verlasse mich auf
diff
zu produzieren, die Nachricht mit einem\
in der ersten Spaltetail
mir die Letzte Zeilediff
's Ausgabe, undgrep
mir zu sagen, wenn die Letzte Zeile ist die Botschaft, die ich bin auf der Suche nach. Wenn das alles funktioniert, dann dieecho
erzeugt einen Zeilenumbruch und die>>
fügt es in die Datei"$i"
. Die Anführungszeichen um"$i"
stellen Sie sicher, dass die Dinge immer noch funktionieren, wenn der Dateiname enthält Leerzeichen.tail -1 $f | grep '\n'
für den Zustand (auf meiner box).Einen einfachen fix für Dateien, die fehlenden newline am Ende der Datei einfach sed; die folgenden Updates die Datei "in-place" (mit den "-i" - option):
Erklärung: alle Dateien suchen (
-type f
), laufensed
ändern Sie die Dateien in-place (-i
), die folgende (-e
) Skript/Ausdruck, mit dem Ende der Datei ($
), und führen Sie die "append" - Aktion (a\
), aber eigentlich nicht geben Sie einen beliebigen text Anhängen (nichts nach die\
), die gehen, um fügen Sie einen Zeilenumbruch an das Ende der Datei, aber nur, wenn es fehlt. Druckt alle Dateien gefunden (fest oder nicht), das ist wahrscheinlich unnötig.Wichtigste Einschränkung ist, dass
sed
Eigenschaften variieren, über Plattformen hinweg, so-i
und-e
möglicherweise oder möglicherweise nicht unterstützt /das gleiche; z.B. ältere Unix, oder MacOS Merkwürdigkeiten erfordern eine etwas andere syntax.OK, nach Klagen in den Kommentaren, es ist meine bessere Lösung.
Erstens wollen Sie wissen, welche Dateien fehlen Zeilenumbrüche:
Nicht super schnell (calling ein paar Prozesse für jede Datei), aber es ist OK für den praktischen Gebrauch.
Nun, wenn Sie es haben, können Sie fügen Sie die neue, mit einem anderen
-exec
:Mögliche Fallstricke:
wenn die Dateinamen sind schlecht, Sie haben zum Beispiel Leerzeichen, müssen Sie möglicherweise
tail -1 \"{}\"
.Oder findet es richtig machen?
können Sie weitere hinzufügen möchten Filterung zu finden, wie
-name \*py
oder ähnliches.nachdenken über mögliche DOS - /Unix-Zeilenumbrüche Durcheinander vor dem Gebrauch (fix, die erste).
EDIT:
Wenn Sie nicht wie die Ausgabe dieser Kommandos (echo einige hex), fügen Sie
-q
zu grep:Versuchen ex-Art:
Und rekursiv (mit eine neue option Platzhalter aktiviert):
Dies ist äquivalent zu
vi -es
. Ändern*.c
zur Erweiterung Ihres Interesses.Den
ex
/vi
würde automatisch Anhängen newline auf speichern, wenn es nicht vorhanden ist.find -type f | while read f; do [[ `tail -c1 "$f"` ]] && echo >> "$f"; done
Ich bin mit
find
stattfor f in *
als Sie rekursiv ist und die Frage war über "riesige Anzahl der Quell-Dateien".Ich bin mit
while read
stattfind -exec
oderxargs
aus performance-Gründen, es spart dem laichen shell-Prozess jedes mal.Ich bin unter Ausnutzung der Tatsache, dass backtick-operators ist wieder die Ausgabe des Befehls "mit der nachgestellten Zeilenumbrüche gelöscht"
man bash
, also für richtig beendet-Dateien backtick leer und echo, werden übersprungen.Den
find | read
paar Fehler bei Dateinamen, die Zeilenumbrüche enthalten, aber es ist einfach zu beheben, wenn erforderlich:find -type f -print0 | while read -d $'\0' f; do [[ `tail -c1 "$f"` ]] && echo >> "$f"; done
Unten ist mein bash-Skript-Lösung. Es wird zuerst überprüft, dass die Datei eine Textdatei ist. Dann, wenn es eine text-Datei, verwendet es die Schwanz-und od - (octal dump), um zu sehen, wenn das Letzte Zeichen ein newline-Zeichen. Wenn nicht, dann ist es fügt ein newline echo:
Durch Befehl Lokalisierung Tim und Norman beantworten Sollen verbessert werden mit "LANG=C" - Präfix, um eine chance zu match 'No newline' Muster mit jedem system, das alle regionalen Parameter
Diese sorgt für ein Ende, leere Zeile für jede Datei legen Sie auf der Kommandozeile das Skript :
Und das Skript erkennt Dateien fehlt es :
Finden, nachdem das tool diese Aufgabe mit kein Glück. Ich entscheiden, zu schreiben, meine eigenen
Dies ist mein python-Skript zu tun, dass job
Es nur append (\r\n) zu " Datei nicht enthält (\n) am Ende der Datei
https://github.com/tranhuanltv/append_newline
Verwendung: append_newline.py .c ./Projekte ./result_dir
Pull-Anfragen, wenn Sie wollen
Ich bin überrascht, niemand hat erwähnt, dass viele einfache text-processing-tools wie Awk fügt ein newline als Nebenwirkung. Hier ist eine einfache Schleife, die eine Datei überschreiben nur, wenn ein Zeilenumbruch war wirklich Hinzugefügt.
(Die temporäre Datei wird offensichtlich ein bisschen eine Warze.)
IDEone demo: http://ideone.com/HpRHcx
Gibt es mehrere Schritte, die hier beteiligt sind:
Schritt 1 erfolgt traditionell mit
find
(nach dem Unix-tradition"jedes Werkzeug eine Sache zu tun und tun es auch"), aber da Xen hat eingebaute Unterstützung, ich bin bequem es zu benutzen. Ich bin vorsichtig, um zu vermeiden Herumspielen mit der .git-Ordner.
Schritt 2 erfolgt mit einem mehrzeiligen regulären Ausdruck passende Dateien, die tun eine abschließende newline, und drucken Sie die Namen der Dateien, die nicht match.
Schritt 3 erfolgt mit einer while - /lese-Schleife statt einer for/in, da letztere fällt für Dateinamen mit Leerzeichen und für extrem lange Listen von Dateien.
Schritt 4 wird ein einfaches echo, Folgen Sie @norman-ramsey-Ansatz.
h/t @anthony-bush https://stackoverflow.com/a/20687956/577438 für die Xen Vorschlag.