cat -e file.txt
gibt:
{"yellow":"mango"}^M$
^M$
{"yellow":"banana"}^M$
^M$
{"yellow":"blabla"}^M$
^M$
und ich hätte gerne nur:
{""yellow":"mango"}^M$
{"yellow":"banana"}^M$
{"yellow":"blabla"}^M$
vorhanden für alle Dateien mit der Erweiterung txt im Ordner. Also habe ich versucht:
find . -type f -name "*.txt" -print0 | xargs -0 sed -i "s/^M$^M$/^M$/g"
ohne Erfolg. Hat jemand eine bessere Idee?
head -n 3 file.txt | od -bc
ergibt:
0000000 173 042 171 145 154 154 157 167 042 072 042 155 141 156 147 157
{ " y e l l o w " : " m a n g o
0000020 042 175 015 012 015 012 173 042 142 141 142 141 142 042 072 042
" } \r \n \r \n { " b a b a b " : "
0000040 155 141 156 147 157 042 175 015 012
m a n g o " } \r \n
0000051
Das:
awk 1 RS='\r\n' ORS= < file.txt
entfernt die neuen Zeilen vollständig (also nicht gut: Ich möchte in jeder Zeile eine der beiden nachfolgenden behalten, aber es passiert etwas).
Antwort1
Sie können verwenden sed -z 's/\r\n\r\n/\r\n/g'
.
Funktioniert normalerweise sed
nur auf einer Zeile gleichzeitig. Durch die Verwendung der -z
Option sed
wird auf Zeilen gearbeitet, die durch 0
Bytes getrennt sind, die normalerweise in einer Textdatei nicht vorhanden sind, sodass die gesamte Datei als eine Zeile behandelt wird und Zeilenumbrüche ersetzt werden können.
(gefunden aufPaketüberflussund hinzugefügte Erklärung)
Antwort2
Sie können auch Zeilen löschen, die nur den Wagenrücklauf enthalten.
Mit GNU Sed:
sed '/^\r$/d' file
Für eine minimale, aber POSIX-kompatible Maschine (hier müssen wir den Wagenrücklauf mit Printf generieren):
sed "/^$(printf "\r")$/d" file
^
entspricht dem Zeilenanfang und dem letzten $
, dem Zeilenende ( \n
).
Zum Beispiel:
$ cat -e file
AB^M$
^M$
CB^M$
^M$
$ sed '/^\r$/d' file|cat -e
AB^M$
CB^M$
Antwort3
Wenn das Entfernen aller Leerzeilen kein Problem darstellt, können Sie Folgendes tun:
perl -wlne '/\S/ and print' old_file > new_file
Und wenn Sie Ihre Datei(en) lieber überschreiben möchten, können Sie den -i
Schalter (in-place) verwenden:
perl -wlni.bak -e '/\S/ and print' file1 file2 file3 ...
Die obige Zeile kopiert die Originaldateien als *.bak
Dateien. Wenn Sie keine Backups anlegen, können Sie diesen .bak
Teil einfach weglassen, wie folgt:
perl -wlni -e '/\S/ and print' file1 file2 file3 ...
(Sie können sogar Platzhalter verwenden, d. h. statt file1 file2 file3 ...
können Sie schreiben file*
.)
Der Vorteil dieses Ansatzes besteht darin, dass Änderungen an allen Ihren Dateien auf einmal vorgenommen werden (anstatt ihn für jede Datei einmal ausführen zu müssen).
Aber denken Sie daran: Es werden nur Zeilen beibehalten, die mindestens ein Zeichen enthalten, das kein Leerzeichen ist. Wenn eine Zeile also nur aus fünf Leerzeichen, einem Tabulator, einem Wagenrücklauf und einem Zeilenvorschubzeichen besteht, wird sie nicht beibehalten.
Antwort4
Verwendung von Raku (der Sprache, die früher als Perl6 bekannt war)
~$ raku -ne '.put if /\S/ ;' test_blank.txt
{"yellow":"mango"}
{"yellow":"banana"}
{"yellow":"blabla"}
Das obige Beispiel druckt nur Zeilen, die keine Leerzeichen enthalten ( \S
entspricht einem einzelnen Zeichen, das kein Leerzeichen ist). Nachfolgend eine gut lesbare Version:
~$ raku -ne '.put if .chars;' test_blank.txt
{"yellow":"mango"}
{"yellow":"banana"}
{"yellow":"blabla"}
HTH.