Сохраняйте изменения на месте с помощью awk
Я изучаю awk
, и я хотел бы знать, есть ли возможность записать изменения в файл, похожие на sed
, где я бы использовал параметр -i
для сохранения изменений в файле.
Я понимаю, что я мог бы использовать перенаправление для записи изменений. Однако есть ли опция awk
для этого?
Ответы
Ответ 1
В последнем выпуске 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
Ответ 2
Если у вас нет GNU awk 4.1.0 или новее...
У вас не будет такой опции, как sed -i
поэтому вместо этого сделайте:
$ awk '{print $0}' file > tmp && mv tmp file
Примечание: -i
не волшебство, он также создает временный файл sed
просто обрабатывает его для вас.
Начиная с GNU awk 4.1.0...
GNU awk
добавил эту функциональность в версии 4.1.0 (выпущена 05.10.2013). Это не так просто, как просто дать -i
как описано в выпущенных заметках:
Новая опция -i (из xgawk) используется для загрузки файлов библиотеки awk. Это отличается от -f тем, что первый неопциональный аргумент обрабатывается как скрипт.
Вам нужно использовать входящий в комплект inplace.awk
файл inplace.awk
чтобы правильно inplace.awk
расширение, например:
$ cat file
123 abc
456 def
789 hij
$ gawk -i inplace '{print $1}' file
$ cat file
123
456
789
Переменная INPLACE_SUFFIX
может использоваться для указания расширения для файла резервной копии:
$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{print $1}' file
$ cat file
123
456
789
$ cat file.bak
123 abc
456 def
789 hij
Я рад, что эта функция была добавлена, но для меня реализация не очень прихотлива, так как сила исходит от краткости языка, и на месте -i inplace
8 символов слишком долго.
Вот ссылка на руководство по официальному слову.
Ответ 3
@sudo_O имеет правильный ответ .
Это не может работать:
someprocess < file > file
Оболочка выполняет перенаправления перед передачей управления некоторому процессу (redirections). Перенаправление >
усекает файл до нулевого размера (перенаправление вывода). Поэтому, к тому времени, когда someprocess запускается и хочет прочитать из файла, для чтения нет данных.
Ответ 4
просто немного взломать, что работает
echo "$(awk '{awk code}' file)" > file
Ответ 5
Альтернативой является использование sponge
:
awk '{print $0}' your_file | sponge your_file
Если вы замените '{print $0}'
на ваши awk script и your_file
на имя файла, который вы хотите изменить на месте.
sponge
полностью поглощает ввод, прежде чем сохранять его в файл.
Ответ 6
Использование tee
awk '{awk code}' file | tee file
команда tee
выполняется и выполняется после завершения команды awk
из-за |
.
Ответ 7
Если вы хотите использовать awk-only без создания временного файла и использовать его с версией!= (gawk 4.1.0):
awk '{a[b++]=$0} END {for(c=0;c<=b;c++)print a[c]>ARGV[1]}' file
Ответ 8
следующее не будет работать
echo $(awk '{awk code}' file) > file
это должно работать
echo "$(awk '{awk code}' file)" > file