Jak zmienić plik na miejscu za pomocą awk? (jak w przypadku „sed -i”)

11

Mam awkskrypt 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 }

Nazywam to w skorupkach

awk new.awk sample.csv

... ale widzę zmiany w terminalu. Jak wprowadzić zmianę w pliku, na przykład podczas używania sed -i?

mittu
źródło

Odpowiedzi:

16

GNU awk(powszechnie spotykany w systemach Linux), od wersji 4.1.0, może zawierać „ awkbibliotekę źródłową” za pomocą -ilub --includew wierszu poleceń. Jedną z bibliotek źródłowych dystrybuowanych wraz z GNU awkjest jedna o nazwie inplace:

$ cat file
hello
there
$ awk -i inplace '/hello/ { print "oh,", $0 }' file
$ cat file
oh, hello

Jak widać, powoduje to, że awkkod wyjściowy zastępuje plik wejściowy. Napis w wierszu therenie jest zachowywany, ponieważ nie jest generowany przez program.

Ze awkskryptem w pliku, używałbyś go tak jak

awk -i inplace -f script.awk datafile

Jeśli awkzmienna INPLACE_SUFFIXjest ustawiona na ciąg znaków, biblioteka utworzy kopię zapasową oryginalnego pliku z tym rozszerzeniem.

awk -i inplace -v INPLACE_SUFFIX=.bak -f script.awk datafile

Jeśli masz kilka plików wejściowych, każdy plik należy edytować osobno w miejscu. Ale możesz wyłączyć edycję w miejscu dla pliku (lub zestawu plików), używając inplace=0wiersza poleceń przed tym plikiem:

awk -i inplace -f script.awk file1 file2 inplace=0 file3 inplace=1 file4

W powyższym poleceniu file3nie będzie edytowane w miejscu.


Aby uzyskać bardziej przenośną „edycję w miejscu” pojedynczego pliku, użyj

tmpfile=$(mktemp)
cp file "$tmpfile" &&
awk '...some program here...' "$tmpfile" >file
rm "$tmpfile"

Spowodowałoby to skopiowanie pliku wejściowego do tymczasowej lokalizacji, a następnie zastosowanie awkkodu do pliku tymczasowego podczas przekierowywania do oryginalnej nazwy pliku.

Wykonanie operacji w tej kolejności (uruchamianie awkpliku tymczasowego, a nie oryginalnego) zapewnia, że ​​metadane pliku (uprawnienia i własność) oryginalnego pliku nie zostaną zmodyfikowane.

Kusalananda
źródło
4

Spróbuj tego.

awk  new.awk sample.csv > tmp.csv && mv -f tmp.csv sample.csv
  • przekieruj wyjście do pliku tymczasowego.
  • następnie przenieś zawartość pliku tymczasowego do oryginalnego pliku.
Siva
źródło
1
Jeśli spojrzysz na wbudowany kod źródłowy awk , robi to dokładnie tak: tworzy plik tymczasowy, przekierowuje tam standardowe wyjście, a na końcu zmienia nazwę na plik wejściowy.
chx