sed / awk / grep / perl … скрипт для поиска содержимого файла внутри файлов и при совпадении изменять его на содержимое другого файла

#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-файлов, их резервного копирования и передачи печатного результата поверх исходного файла. Спасибо