#awk #sed #grep
#awk #sed #grep
Вопрос:
Мне нужно найти и заменить встроенный svg-код в однострочных файлах, сгенерированных HTML / JS.
Я вижу много примеров сценариев sed и / или awk для сопоставления содержимого файла в другом файле, но я сталкиваюсь с двумя проблемами: либо я не могу понять, как заменить соответствующий файл содержимым 3-го файла, либо поиск действителен, только если вся строка соответствует файлу (файлы, в которых выполняется поиск, представляют собой однострочный HTML со всем склеенным кодом …).
чтобы поместить его в простой псевдокод, я ищу:
IF oldImage.svg IS MATCHED IN file.html THEN REPLACE MATCHED TEXT BY newImage.svg
Я знаю, что весь svg-файл сопоставляется внутри html-файлов, поскольку я успешно запустил grep -wFf oldImage.svg file.html
.
Кроме того, если бы решение могло быть рекурсивным для всех файлов во вложенных папках, это было бы большим плюсом.
.
Обновить:
Пример, запрошенный @anubhava
OldImage.svg
<svg>old file graphics...</svg>
newImage.svg
<svg>great new graphics...</svg>
file.html (перед сценарием)
<html>
<head>
<title> example </title>
</head>
<body>
<svg>old file graphics...</svg>
</body>
</html>
file.html (после запуска скрипта)
<html>
<head>
<title> example </title>
</head>
<body>
<svg>great new graphics...</svg>
</body>
</html>
(имея в виду, что я написал многострочный пример для удобства чтения, но HTML-код, который я собираюсь использовать, весь склеен в одну строку или, по крайней мере, в одной строке есть несколько разных тегов)
Комментарии:
1. это многострочные файлы с правильной идентификацией. Я предполагаю, что мне также нужно игнорировать различия в переводах строк, хороший момент
2. Если ваши реальные данные содержат несколько строк, убедитесь, что пример, который вы предоставляете в своем вопросе для тестирования, содержит несколько строк. Убедитесь, что ваш пример охватывает наихудший случай, а не только тривиальный случай солнечного дня, чтобы вы получили ответ, который обрабатывает его. Также сообщите нам, используете ли вы или можете использовать GNU awk (
awk --version
вам скажут).
Ответ №1:
awk '
ARGIND == 1 { old=$0 }
ARGIND == 2 { new=$0 }
ARGIND == 3 {
if ( s = index($0,old) ) {
$0 = substr($0,1,s-1) new substr($0,s length(old))
}
print
}
' oldImage.svg newImage.svg file.html
Выше используется GNU awk для ARGIND, если у вас его нет, добавьте строку вверху, которая гласит:
FNR == 1 { ARGIND }
Комментарии:
1. Вам просто нужно было бы установить
-v RS='^$'
или аналогичный для обработки многострочных данных, но это не то, что OP показал в своем примере, и они сказали в вопросе, с которым они работалиsingle line ... files
.2. Ах, я понимаю, хорошо, если / когда OP опубликует более репрезентативный пример, я обновлю свой ответ, чтобы он соответствовал. Это будет тривиально настроить, но есть пара вещей, которые следует учитывать (например, есть только 1 замена на строку или на файл или …?), И я не хочу делать это без конкретного примера для проверки.
3. было довольно легко адаптировать оба svg-файла к однострочным файлам (я не знал, нужно ли мне это, поскольку я изменил их, прежде чем понял, что macOS awk — это не gawk, и мне нужна была дополнительная строка вверху). Я выполнил быстрый цикл bask for для циклического просмотра HTML-файлов, их резервного копирования и передачи печатного результата поверх исходного файла. Спасибо