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


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

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

8 91

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 в том, что первый аргумент, не являющийся опцией рассматривается как скрипт.

вы должны использовать в комплекте 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 символов, чтобы долго И. М. О..

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

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

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

someprocess < file > file

оболочка выполняет перенаправления до передача управления someprocess (редиректы). Элемент > перенаправление приведет к усечению файла до нулевого размера (перенаправление вывода). Поэтому к тому времени, когда 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

через тройник

 awk '{awk code}' file | tee file

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