Ersetzen Sie zwei aufeinanderfolgende CR durch einen

Ersetzen Sie zwei aufeinanderfolgende CR durch einen

cat -e file.txtgibt:

{"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 sednur auf einer Zeile gleichzeitig. Durch die Verwendung der -zOption sedwird auf Zeilen gearbeitet, die durch 0Bytes 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 -iSchalter (in-place) verwenden:

perl -wlni.bak -e '/\S/ and print' file1 file2 file3 ...

Die obige Zeile kopiert die Originaldateien als *.bakDateien. Wenn Sie keine Backups anlegen, können Sie diesen .bakTeil 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 ( \Sentspricht 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.

https://raku.org
https://rakudo.org/downloads

verwandte Informationen