Uczę się awk
i chciałbym wiedzieć, czy jest możliwość zapisania zmian do pliku, podobnie jak w sed
przypadku, gdybym skorzystał z -i
opcji zapisywania zmian w pliku.
Rozumiem, że mógłbym użyć przekierowania do zapisania zmian. Czy jest jednak opcja, awk
aby to zrobić?
awk
może użyć poniższego linku również stackoverflow.com/questions/59243104/ ... fyi, proszę.Odpowiedzi:
W GNU Awk 4.1.0 (wydanym 2013) i nowszych ma opcję edycji plików „inplace” :
Przykładowe użycie:
$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1 file2 file3
Aby zachować kopię zapasową:
$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{ gsub(/foo/, "bar") } > { print }' file1 file2 file3
źródło
inplace
jest właściwie biblioteką dołączonągawk
zgodnie z odpowiedzią iiSeymour , więcinplace
jest to coś, co można dołączyć jako plikincludefile
.Chyba że masz GNU awk 4.1.0 lub nowszy ...
Nie będziesz mieć takiej opcji jak opcja seda,
-i
więc zamiast tego zrób:$ awk '{print $0}' file > tmp && mv tmp file
Uwaga:
-i
to nie jest magia, to również tworzenie pliku tymczasowego, którysed
obsługuje go za Ciebie.Od GNU awk 4.1.0 ...
GNU awk
dodano tę funkcjonalność w wersji 4.1.0 (wydana 05.10.2013) . Nie jest to tak proste, jak po prostu podanie-i
opcji, jak opisano w opublikowanych uwagach:Aby
inplace.awk
poprawnie wywołać rozszerzenie, musisz użyć dołączonego pliku dołączanego :$ cat file 123 abc 456 def 789 hij $ gawk -i inplace '{print $1}' file $ cat file 123 456 789
Zmiennej
INPLACE_SUFFIX
można użyć do określenia rozszerzenia pliku kopii zapasowej:$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{print $1}' file $ cat file 123 456 789 $ cat file.bak 123 abc 456 def 789 hij
Cieszę się, że ta funkcja została dodana, ale dla mnie implementacja nie jest zbyt dziwna, ponieważ moc pochodzi ze zwięzłości języka i
-i inplace
jest o 8 znaków za długa imo .Oto link do podręcznika z oficjalnym słowem.
źródło
awk '{ gsub(/foo/, "bar" ) } ; { print $0 }' file > tmp.txt && mv -v tmp.txt file
:?awk '{print $0}' file | sponge file
przy użyciusponge
odmoreutils
.tylko mały hack, który działa
echo "$(awk '{awk code}' file)" > file
źródło
-i inplace
przerwy metoda hardlinki ten siekać następująco hardlinki ♥♥@sudo_O ma właściwą odpowiedź .
To nie może działać:
someprocess < file > file
Powłoka wykonuje przekierowania przed przekazaniem kontroli do jakiegoś procesu ( przekierowania ).
>
Przekierowania będzie obcina pliku zerowej wielkości ( wyjściowego przekierowanie ). Dlatego zanim jakiś proces zostanie uruchomiony i chce odczytać z pliku, nie ma danych do odczytania.źródło
Alternatywą jest użycie
sponge
:awk '{print $0}' your_file | sponge your_file
Gdzie zastępujesz
'{print $0}'
skryptem awk iyour_file
nazwą pliku, który chcesz edytować w miejscu.sponge
całkowicie pochłania dane wejściowe przed zapisaniem ich do pliku.źródło
sponge
jest częściąmoreutils
. Więc nie będzie domyślnie obecny w większości systemów. Ale wygląda na to, że przynajmniejsponge
sam jest wystarczająco przenośny i można go uruchomić prawie wszędzie.tee
-based jest to, żesponge
przed zapisaniem odczyta wszystko do pamięci RAM, dlatego będzie się zawieszać na dużych plikach.śledzenie nie będzie działać
echo $(awk '{awk code}' file) > file
to powinno działać
echo "$(awk '{awk code}' file)" > file
źródło
W przypadku, gdy potrzebujesz rozwiązania tylko awk bez tworzenia pliku tymczasowego i nadającego się do użytku z wersją! = (Gawk 4.1.0):
awk '{a[b++]=$0} END {for(c=0;c<=b;c++)print a[c]>ARGV[1]}' file
źródło
Korzystanie z koszulki
awk '{awk code}' file | tee file
tee
miejsce odbioru i polecenia wykonywane poawk
komenda jest zakończona ze względu na|
.źródło