awk сохранить изменения на месте

Я учусь awk и я хотел бы знать, есть ли возможность записать изменения в файл, похожие на sed где я хотел бы использовать -i возможность сохранения изменений в файл.

Я понимаю, что могу использовать перенаправление для записи изменений. Однако есть ли опция в awk Что делать?

8 ответов


в последнем GNU Awk (с 4.1.0 освобожден), он имеет опцию редактирование файлов"inplace":

[...] Расширение "inplace", построенное с использованием нового объекта, может использоваться для имитации GNU"sed -i" функции. [...]

пример использования:

$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1 file2 file3

сохранить резервную копию:

$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{ gsub(/foo/, "bar") }
> { print }' file1 file2 file3

если у вас нет GNU awk 4.1.0 или более поздней версии...

у вас не будет такого варианта как sed-ы -i вариант так вместо этого сделать:

$ awk '{print }' file > tmp && mv tmp file

Примечание:-i - это не магия, это также создает временный файл sed просто обрабатывает его для вас.


начиная с GNU awk 4.1.0...

GNU awk добавлена эта функциональность в версии 4.1.0 (освобожден 10/05/2013). Это не так просто. вперед, как просто давая -i опция, как описано в выпущенных примечаниях:

опция new-i (от xgawk) используется для загрузки файлов библиотеки awk. Это отличается от-f тем, что первый аргумент non-option рассматривается как скрипт.

вы должны использовать в комплекте inplace.awk включить файл, чтобы вызвать расширение правильно так:

$ cat file
123 abc
456 def
789 hij

$ gawk -i inplace '{print }' file

$ cat file
123
456
789

переменная INPLACE_SUFFIX можно использовать для указания расширения резервной копии файл:

$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{print }' file

$ cat file
123
456
789

$ cat file.bak
123 abc
456 def
789 hij

Я рад, что эта функция была добавлена, но для меня реализация не очень неловко, как власть с лаконичностью языка и -i inplace это 8 символов для long И. М. О..

вот ссылка на руководство для официального слова.


@sudo_O имеет право ответ.

это не может работать:

someprocess < file > file

оболочка выполняет перенаправления до передача управления someprocess (редиректы). The > перенаправление обрезает файл до нулевого размера (перенаправление вывода). Поэтому к тому времени, когда someprocess запускается и хочет читать из файла, для него нет данных для чтения.


просто немного взломать, что работает

echo "$(awk '{awk code}' file)" > file

альтернативой является использование sponge:

awk '{print }' your_file | sponge your_file

где вместо '{print }' по вашему сценарию awk и your_file по имени файла, который вы хотите отредактировать на месте.

sponge полностью поглощает ввод перед сохранением его в файл.


в случае, если вы хотите awk-только решение без создания временного файла и может использоваться с версией!=(gawk 4.1.0):

awk '{a[b++]=} END {for(c=0;c<=b;c++)print a[c]>ARGV[1]}' file

следовать не будет работать

echo $(awk '{awk code}' file) > file

это должно работать

echo "$(awk '{awk code}' file)" > file

использование tee

 awk '{awk code}' file | tee file

на tee команда выполняется после awk команда завершена из-за |.