awk '/^nameserver/ && !modif { printf("nameserver 127.0.0.1\n"); modif=1 } {print}' testfile.txt
Он выводит вывод, но я хочу записать вывод в тот же файл. В моем примере testfile.txt
.
awk '/^nameserver/ && !modif { printf("nameserver 127.0.0.1\n"); modif=1 } {print}' testfile.txt
Он выводит вывод, но я хочу записать вывод в тот же файл. В моем примере testfile.txt
.
Невозможно само по себе. Вам нужен второй временный файл, потому что вы не можете читать и перезаписывать один и тот же файл. Что-то вроде:
awk '(PROGRAM)' testfile.txt > testfile.tmp && mv testfile.tmp testfile.txt
Программа mktemp
полезна для создания уникальных временных имен файлов.
Есть некоторые хаки для избежания временного файла, но они в основном полагаются на кеширование и чтение буферов и быстро становятся нестабильными для больших файлов.
Так как GNU Awk 4.1.0, существует расширение "inplace", поэтому вы можете:
$ 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 sed -i
.
Смотрите: Включение редактирования файла на месте
Несмотря на то, что использование временного файла верное, мне это не нравится, потому что:
вы должны быть уверены, что не удалите еще один временный файл (да, вы можете использовать mktemp - это довольно полезный инструмент)
вы должны позаботиться о его удалении (или перемещая его, как сказал thiton) ВКЛЮЧАЯ, когда ваш script сбой или остановка до конца (поэтому удаление временных файлов в конце script не так мудры)
он генерирует IO на диске (не так много, но мы можем сделать его легче)
Итак, мой метод во избежание временного файла прост:
my_output="$(awk '(PROGRAM)' source_file)"
echo "$my_output" > source_file
Обратите внимание на использование двойных кавычек либо при захвате вывода из awk-команды AND при использовании эха (если вы этого не сделаете, у вас не будет новых строк).
Вы также можете использовать sponge
из moreutils.
Например
awk '!a[$0]++' file|sponge file
удаляет повторяющиеся строки и
awk '{$2=10*$2}1' file|sponge file
умножает второй столбец на 10.
Приходилось делать учетную запись при просмотре "awk" и "невозможно" в одном предложении. Вот решение awk-only без создания временного файла:
awk '{a[b++]=$0} END {for(c=1;c<=b;c++)print a[c]>ARGV[1]}' file
Попробуйте включить оператор в свой awk файл, чтобы вы могли найти вывод в новом файле. Здесь total - вычисленное значение.
print $total, total >> "new_file"