.png)
Ich habe ein awk
Skript new.awk
:
BEGIN { FS = OFS = "," }
NR == 1 {
for (i = 1; i <= NF; i++)
f[$i] = i
}
NR > 1 {
begSecs = mktime(gensub(/[":-]/, " ", "g", $(f["DateTime"])))
endSecs = begSecs + $(f["TotalDuration"])
$(f["CallEndTime"]) = strftime("%Y-%m-%d %H:%M:%S", endSecs)
}
{ print }
Ich rufe dies in der Shell auf
awk new.awk sample.csv
... aber ich kann die Änderungen im Terminal sehen. Wie kann ich die Änderung direkt in der Datei vornehmen, wie bei Verwendung von sed -i
?
Antwort1
GNU awk
(häufig auf Linux-Systemen zu finden) kann seit Version 4.1.0 eine „ awk
Quellbibliothek“ mit -i
oder --include
auf der Kommandozeile einbinden (sieheWie verwende ich die Option -i oder die Direktive @include von gawk sicher?zusammen mit Stéphanes Kommentar unten zu den damit verbundenen Sicherheitsproblemen). Eine der mit GNU verteilten Quellbibliotheken awk
heißt inplace
:
$ cat file
hello
there
$ awk -i inplace '/hello/ { print "oh,", $0 }' file
$ cat file
oh, hello
Wie Sie sehen, wird dadurch die Eingabedatei durch die Ausgabe des awk
Codes ersetzt. Die Zeile mit dem Inhalt there
wird nicht beibehalten, da das Programm sie nicht ausgibt.
Mit einem awk
Skript in einer Datei würden Sie es wie folgt verwenden:
awk -i inplace -f script.awk datafile
Wenn die awk
Variable INPLACE_SUFFIX
auf eine Zeichenfolge gesetzt ist, erstellt die Bibliothek eine Sicherungskopie der Originaldatei mit dieser als Dateinamensuffix.
awk -i inplace -v INPLACE_SUFFIX=.bak -f script.awk datafile
Wenn Sie mehrere Eingabedateien haben, wird jede Datei einzeln direkt bearbeitet. Sie können die direkte Bearbeitung jedoch für eine Datei (oder eine Gruppe von Dateien) deaktivieren, indem Sie inplace=0
in der Befehlszeile vor dieser Datei Folgendes eingeben:
awk -i inplace -f script.awk file1 file2 inplace=0 file3 inplace=1 file4
Im obigen Befehl file3
würde keine Bearbeitung an Ort und Stelle erfolgen.
Für eine portablere „In-Place-Bearbeitung“ einer einzelnen Datei verwenden Sie
tmpfile=$(mktemp)
cp file "$tmpfile" &&
awk '...some program here...' "$tmpfile" >file
rm "$tmpfile"
Dadurch wird die Eingabedatei an einen temporären Speicherort kopiert und der awk
Code anschließend auf die temporäre Datei angewendet, während eine Umleitung zum ursprünglichen Dateinamen erfolgt.
Durch das Ausführen der Vorgänge in dieser Reihenfolge (Ausführen awk
auf der temporären Datei, nicht auf der Originaldatei) wird sichergestellt, dass die Dateimetadaten (Berechtigungen und Eigentumsrechte) der Originaldatei nicht geändert werden.
Antwort2
Versuche dies.
awk new.awk sample.csv > tmp.csv && mv -f tmp.csv sample.csv
- Leiten Sie die Ausgabe in eine temporäre Datei um.
- Verschieben Sie dann den Inhalt der temporären Datei in die Originaldatei.