Я столкнулся с вопросом (на самом SO), где OP должен выполнять редактирование и сохранять операции в самих Input_file (s).
Я знаю, что для одного Input_file мы могли бы сделать следующее:
awk '{print "test here..new line for saving.."}' Input_file > temp && mv temp Input_file
Теперь предположим, что нам нужно внести изменения в один и тот же формат файлов (предположим, здесь .txt).
Что я пробовал / думал для этой проблемы: его подход заключается в прохождении цикла for .txt файлов, и вызов singleawk
- это болезненный и НЕ рекомендуемый процесс, поскольку он будет тратить ненужные циклы ЦП и для большего количества файлов будет больше медленный.
Итак, что можно сделать здесь, чтобы выполнить редактирование на месте для нескольких файлов с NON GNU, awk
который не поддерживает опцию на месте. Я также прошел через эту ветку Сохранение изменений на месте с помощью awk, но для NON GNU awk Vice нет ничего особенного и для изменения нескольких файлов на месте внутри awk
себя, так как не GNU awk не будет иметь inplace
опцию для этого.
ПРИМЕЧАНИЕ. Почему я добавляюbash
тег, поскольку в своей части ответа я использовал команды bash, чтобы переименовать временные файлы в их настоящие имена Input_file, поэтому добавляю их.
РЕДАКТИРОВАТЬ: В соответствии с комментарием Эда сэра, добавив здесь пример примеров, хотя назначение кода этого потока может быть использовано и для общего редактирования на месте.
Пример входного файла (ов):
cat test1.txt
onetwo three
tets testtest
cat test2.txt
onetwo three
tets testtest
cat test3.txt
onetwo three
tets testtest
Образец ожидаемого выхода:
cat test1.txt
1
2
cat test2.txt
1
2
cat test3.txt
1
2
awk
(возможно, в подоболочке) или{...}
закрытую группу, а затем записать результаты в нужный выходной файл (либо для каждого входного файла, или объединенный файл для всех входных файлов). Затем вы просто перенаправляете выходные данные вложенной или заключенной в скобки группы в текущий файл, в который выполняется запись? Простое включение строки входных файлов послеawk
команды будет последовательно обрабатывать все файлы (или что-то подобное) ??awk {..} file1 .. fileX
записью измененного файла, как, например,temp01
и в вашей следующей итерации при обработке следующего файла, используйте a,mv -f tmp01 input01
чтобы перезаписать входной файл с измененными данными; или (2) просто напишите новый каталог./tmp/tmp01 ... ./tmp/tmp0X
во время выполненияawk
скрипта и выполните цикл с файлами в./tmp
каталоге и, например,mv -f "$i" "input_${i##*[^0-9]}"
(или любым другим расширением, которое вам нужно, чтобы заменить старые входные файлы.awk
полного завершения кода, 2-й вариант почти такой же, как я использую в моем предложении, будет будьте благодарны, если вы можете сообщить свои мысли об этом решении, сэр.Ответы:
Поскольку главная цель этой темы - как сделать SAVE на месте в NON GNU,
awk
поэтому я сначала публикую его шаблон, который поможет любому в любых требованиях, им нужно добавить / добавитьBEGIN
иEND
раздел в своем коде, сохраняя свой основной БЛОК согласно их требование, и это должно сделать редактирование на месте тогда:ПРИМЕЧАНИЕ. После этого все выходные данные будут записаны в файл output_file, поэтому, если вы хотите напечатать что-либо в стандартный вывод, добавьте только
print...
оператор без> (out)
последующего.Общий шаблон:
Конкретное предоставленное решение образца:
Я придумал следующий подход внутри
awk
себя (для добавленных примеров мой подход состоит в том, чтобы решить эту проблему и сохранить результат в самом Input_file)ПРИМЕЧАНИЕ: это всего лишь тест для сохранения отредактированных выходных данных в самих файлах Input_file, можно использовать его раздел BEGIN вместе с разделом END в их программе, основной раздел должен соответствовать требованию конкретного вопроса.
Справедливое предупреждение: также, так как этот подход создает новый временный выходной файл в пути, поэтому лучше убедиться, что у нас достаточно места в системах, хотя в конечном результате он будет сохранять только основные входные_файлы, но во время операций ему нужно пространство в каталоге system /
Ниже приведен тест для приведенного выше кода.
Выполнение программы на примере: Предположим, что следующие файлы
.txt
Input_file:Теперь, когда мы запускаем следующий код:
ПРИМЕЧАНИЕ. Я специально разместил
ls -lhtr
вsystem
разделе, чтобы увидеть, какие выходные файлы он создает (временная основа), потому что позже он переименует их в их фактическое имя.Когда мы выполняем сценарий
ls -lhtr
послеawk
запуска, мы можем видеть только.txt
файлы там.Пояснение: Добавление подробного объяснения вышеупомянутой команды здесь:
источник
FNR==1
блоке, вы все равно можете сохранить изменения на месте. Какawk 'FNR==1{system("rm " FILENAME)} {print "new lines" > FILENAME}' files...
. Это вообще ненадежно (полная потеря данных, скорее всего, произойдет), но, тем не менее, в основном работает нормально: DЯ бы, наверное, пошел с чем-то вроде этого, если бы я попытался сделать это:
Я бы предпочел сначала скопировать исходный файл в резервную копию, а затем поработать с сохранением изменений оригинала, но при этом изменилось бы значение переменной FILENAME для каждого входного файла, что нежелательно.
Обратите внимание, что если у вас есть исходные файлы с именем
whatever.bak
илиwhatever.new
в вашем каталоге, вы бы перезаписали их временными файлами, поэтому вам также нужно добавить тест для этого. Вызов дляmktemp
получения имен временных файлов будет более надежным.FAR более полезной вещью, которая будет иметься в этой ситуации, будет инструмент, который выполняет любую другую команду и выполняет часть редактирования «на месте», поскольку она может использоваться для обеспечения редактирования «на месте» для POSIX sed, awk, grep, tr, чего угодно и не требует, чтобы вы меняли синтаксис вашего скрипта на
print > out
и т. д. каждый раз, когда вы хотите напечатать значение. Простой, хрупкий пример:который вы бы использовали следующим образом:
Одна очевидная проблема с этим
inedit
сценарием - это сложность идентификации файлов ввода-вывода отдельно от команды, когда у вас есть несколько входных файлов. В приведенном выше сценарии предполагается, что все входные файлы отображаются в виде списка в конце команды, и команда запускается для них по одному, но, конечно, это означает, что вы не можете использовать его для сценариев, которым требуется 2 или более файлов в время, например:или сценарии, которые устанавливают переменные между файлами в списке аргументов, например:
Делая его более надежным, оставьте его в качестве упражнения для читателя, но посмотрите на
xargs
синопсис как на отправную точку того, какinedit
должен работать робаст :-).источник
Решение оболочки простое и, вероятно, достаточно быстрое:
Ищите другое решение только в том случае, если вы убедительно продемонстрировали, что это слишком медленно. Помните: преждевременная оптимизация - корень всего зла.
источник