Wie kann ich das letzte Komma-Trennzeichen am Ende einer Datei entfernen?

9

Wie kann das letzte Komma-Trennzeichen aus einer Datei unter Linux entfernt werden?

Beispiel einer Datei:

"is_supported_kafka_ranger" : "true",
"kafka_log_dir" : "/var/log/kafka",
"kafka_pid_dir" : "/var/run/kafka",
"kafka_user" : "kafka",
"kafka_user_nofile_limit" : "128000",
"kafka_user_nproc_limit" : "65536",

erwartete Ergebnisse:

"is_supported_kafka_ranger" : "true",
"kafka_log_dir" : "/var/log/kafka",
"kafka_pid_dir" : "/var/run/kafka",
"kafka_user" : "kafka",
"kafka_user_nofile_limit" : "128000",
"kafka_user_nproc_limit" : "65536"
Yael
quelle

Antworten:

22

Verwenden von GNU sed:

sed -i '$s/,$//' file

Das heißt, in der letzten Zeile ( $) ersetzen Sie ( s) das Komma am Ende der Zeile ( ,$) durch nichts.

Die Änderung wird aufgrund der -iFlagge an Ort und Stelle vorgenommen.

Mit Standard sed:

sed '$s/,$//' <file >file.new &&
mv file.new file

Hinweis: Jemand hat eine Bearbeitung vorgeschlagen, um "in der letzten Zeile" in "zuletzt in der Zeile" (oder etwas Ähnliches) zu ändern. Das ist falsch. Wenn $eine Adresse angegeben wird (eine Zeile, in der ein Bearbeitungsbefehl angewendet werden soll), bezieht sie sich auf die letzte Zeile des Streams oder der Datei. Dies unterscheidet sich von der Verwendung $in einem regulären Ausdruck.

Kusalananda
quelle
6

Für die direkte Bearbeitung, die Sie verwenden können ed, wird die Position beim Öffnen standardmäßig auf die letzte Zeile gesetzt, sodass Sie die letzte Zeile nicht explizit ansprechen müssen:

ed file
s/,$//
wq

Oder als Einzeiler

printf 's/,$//\nwq\n' | ed -s file
Steeldriver
quelle
2
In Bash können Sie auf Folgendes verzichten printf: ed -s file <<< $'s/,$//\nwq\n'(Das Schlüsselwort für die Suche im Bash-Handbuch lautet "here string").
Ruslan
5

Im Allgemeinen würde ich wahrscheinlich mit der einfachen sedLösung gehen. Wenn Ihre Eingabedateien jedoch sehr groß sind, möchten Sie möglicherweise eine Lösung, die nicht die Zeit benötigt, um die gesamte Datei zu lesen, nur um die letzten paar Bytes zu bearbeiten.

Wenn Sie zu 100% sicher sind, dass Ihre Eingabedatei mit einem Komma gefolgt von einer neuen Zeile endet, können Sie truncatediese beiden letzten Zeichen entfernen und dann eine letzte neue Zeile anhängen:

filesize=$(stat -L --format "%s" lastcomma.txt)
truncate --size $((filesize - 2)) lastcomma.txt 
echo >> lastcomma.txt 

Dies setzt eine Distribution voraus, die GNU Truncate oder ein Äquivalent enthält.


@ StéphaneChazelas weist darauf hin, dass GNU truncatejetzt unterstützt truncate -s -2 file, die Datei um zwei Bytes zu verkürzen ; Wenn Sie diese Version haben, vereinfacht sich das Folgende zu:

truncate --size -2 lastcomma.txt
echo >> lastcomma.txt 
Digitales Trauma
quelle
... und ein Dateisystem, das unterstützttruncate
malat
@malat, welches Dateisystem unterstützt das Abschneiden nicht?
Stéphane Chazelas
@ StéphaneChazelas Richtig, das ist schlecht formuliert. Wie wäre es mit: [...] und einem Dateisystem, das spärliche Dateien unterstützt, um eine effiziente zu haben truncate. Das OP beschreibt seine Lösung beginnend mit: "Wenn Ihre Eingabedateien riesig sind" ... daher mein Kommentar.
Malat
2
GNU truncateunterstützt jetzt das truncate -s -2 fileVerkürzen der Datei um zwei Bytes. Sie möchten stat -Lwie für Symlinks verwenden, Sie möchten die Größe des Ziels des Symlinks (oder einfach size=$(wc -c < file)).
Stéphane Chazelas
2
@malat, Sie benötigen keine Unterstützung für spärliche Dateien, um Dateien abzuschneiden. Hier schneiden wir Daten vom Ende der Datei ab.
Stéphane Chazelas