Использование gawk для замены шаблона текста содержимым файла, имя файла которого находится внутри текста
Я пытаюсь заменить текст внутри текстового файла в соответствии с определенными критериями.
Например, если у меня есть три текстовых файла, в которых external.txt содержит:
Blah Blah Blah
INCLUDE inner1.txt
Etcetera Etcetera
INCLUDE inner2.txt
end of file
И inner1.txt, содержащий:
contents of inner1
И inner2.txt, содержащий:
contents of inner2
В конце замены файл external.txt будет выглядеть так:
Blah Blah Blah
contents of inner1
Etcetera Etcetera
contents of inner2
end of file
Общий шаблон будет таким, что для каждого экземпляра слова "ВКЛЮЧИТЬ" замените всю эту строку содержимым файла, имя файла которого следует непосредственно за экземпляром "ВКЛЮЧИТЬ", который в одном случае будет являться inner1.txt, а во втором case будет inner2.txt.
Проще говоря, возможно ли, чтобы gawk мог определить, какой текстовый файл должен быть встроен во внешний текстовый файл, на основе самого содержимого, подлежащего замене во внешнем текстовом файле?
4 ответа
С GNU awk:
awk --load readfile '{if ($1=="INCLUDE") {printf readfile($2)} else print}' outer.txt
С гну сед
sed -E 's/( *)INCLUDE(.*)/printf "%s" "\1";cat \2/e' outer.txt
Если вы установите бит +x в файле редактирования ('chmod +x edit-file'), вы можете сделать:
g/include/s//cat/\
.w\
d\
r !%
w
q
Пояснение:
g/include/s//cat/\
Запускает глобальную команду.
.w\
(из глобального контекста), перезаписывает файл редактирования только текущей строкой (фактически: 'cat included_file', где вы заменяете include_file на имя рассматриваемого файла.)
d\
(из глобального контекста) удаляет текущую строку из буфера. (т. е. удаляет 'include included_file', опять же, include_file, обозначающий рассматриваемый файл).
r !%
(из глобального контекста), считывает вывод выполнения файла по умолчанию (который редактируется нами и был перезаписан выше с помощью "cat...").
w
(наконец, вне глобального контекста). Записывает (сохраняет) буфер обратно в файл редактирования.
q
уволиться.
Другойed
подход будет примерно таким:
#!/bin/sh
ed -s outer.txt <<-'EOF'
/Blah Blah Blah/+1kx
/end of file/-1ky
'xr inner.txt
'xd
'yr inner2.txt
'yd
%p
Q
EOF
Изменять
Q
кw
если требуется редактирование на местеУдалить
%p
чтобы заглушить вывод.