Как записать результаты поиска в тот же файл, используя команду awk - PullRequest
27 голосов
/ 05 ноября 2011
awk '/^nameserver/ && !modif { printf("nameserver 127.0.0.1\n"); modif=1 } {print}' testfile.txt

Отображается вывод, но я хочу записать вывод в тот же файл.В моем примере testfile.txt.

Ответы [ 6 ]

43 голосов
/ 05 ноября 2011

Невозможно само по себе. Вам нужен второй временный файл, потому что вы не можете прочитать и перезаписать один и тот же файл. Что-то вроде:

awk '(PROGRAM)' testfile.txt > testfile.tmp && mv testfile.tmp testfile.txt

Программа mktemp полезна для генерации уникальных временных имен файлов.

Есть несколько способов избежать временного файла, но они в основном полагаются на буферы кэширования и чтения и быстро становятся нестабильными для больших файлов.

9 голосов
/ 20 мая 2015

Начиная с GNU Awk 4.1.0, есть расширение «на месте», поэтому вы можете сделать:

$ 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.

См .: Включение редактирования файла на месте

8 голосов
/ 20 декабря 2013

Несмотря на то, что использование временного файла является правильным, мне это не нравится, потому что:

  • вы должны быть уверены, что не удалили другой временный файл (да, вы можете использовать mktemp - это довольно полезный инструмент)

  • Вы должны позаботиться об его удалении (или перемещении, как сказал Титон), ВКЛЮЧАЯ, когда ваш скрипт завершается сбоем или останавливается до конца (поэтому удаление временных файлов в конце скрипта не так уж и разумно) *

  • это генерирует IO на диске (хорошо, не так много, но мы можем сделать это легче)

Так что мой способ избежать временного файла прост:

my_output="$(awk '(PROGRAM)' source_file)"
echo "$my_output" > source_file

Обратите внимание на использование двойных кавычек либо при получении вывода из команды awk, И при использовании echo (если вы этого не сделаете, у вас не будет символов новой строки).

4 голосов
/ 30 октября 2014

Вы также можете использовать sponge из moreutils .

Например

awk '!a[$0]++' file|sponge file

удаляет повторяющиеся строки и

 awk '{$2=10*$2}1' file|sponge file

умножает второй столбец на 10.

2 голосов
/ 20 августа 2015

Пришлось создать учетную запись, увидев «awk» и «not not» в одном предложении.Вот решение только для awk без создания временного файла:

awk '{a[b++]=$0} END {for(c=1;c<=b;c++)print a[c]>ARGV[1]}' file
0 голосов
/ 15 июня 2017

Попробуйте включить оператор в ваш awk-файл, чтобы вы могли найти вывод в новом файле. Здесь сумма является расчетным значением.

print $total, total >> "new_file" 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...