Назад | Перейти на главную страницу

sed вставить из file.txt в несколько файлов

У меня есть команда sed & find

find /home/www/ -name footer.php -exec sed -i 's/<\/body>/testmoe\n<\/body>/'

что мне нужно заменить testmoe данными в file.txt, чтобы он был,

find /home/www/ -name footer.php -exec sed -i 's/<\/body>/file.txt\n<\/body>/'

любое предложение исправить мою команду

Чтобы немного улучшить ответ @Iain, я думаю, вы можете сделать это всего за один проход следующим образом:

#!/bin/sh
sed -i '/<\/body/ {
    r /path/to/file
    a </body>
    d
}' $1

Это ищет </body>, вставляет файл в буфер, добавляет </body> в буфер, а затем удаляет оригинал </body>, который, как правильно указал Иэн, не может быть перемещен.

С участием sed вам нужно сделать несколько проходов, поскольку /RE/r <filename> команда вставляет содержимое <filename> в вывод после / RE /. Самый простой способ сделать это с помощью sed -

  • Вставьте 'текст маркера' перед / RE / в первом проходе
  • Вставьте содержимое файла после «текста маркера» на втором этапе.
  • Удалите "текст маркера" на третьем этапе.

Это проще всего сделать с помощью скрипта, который можно вызвать из find

#!/bin/bash

sed -i '/<\/body>/i xyzzy' $1
sed -i '/xyzzy/r /path/to/file.txt' $1
sed -i  '/xyzzy/d' $1

затем

find /home/www -name footer.php -exec /path/to/script {} \;

Я знаю, что это немного похоже на старую шутку Западной Страны («Вы знаете, как добраться до Йовила?» «Если бы я хотел добраться до Йовила, я бы не начал отсюда, сэр»), но я бы не стал использовать его. sed.

Пытаться

perl -ne '$temp = $_ ; if ( $_ =~ /<\/body>/ ) { open FD2, "file.txt" ; while (<FD2>) { print  $_ ; } } ; print $temp;' < foo > bar

Однострочники perl могут быть немного, ну, загадочными, так что вот разбивка того, что происходит. Сценарий perl:

  1. perl -n построчно проходит через STDIN; для каждой строки -e вызывает скрипт в одинарных кавычках, в котором:
  2. $temp = $_ сохраняет строку во временном буфере
  3. if ( $_ =~ /<\/body>/ ) ищет строку, содержащую </body>
  4. open FD2, "file.txt" ; while (<FD2>) { print $_ ; }: когда </body> был найден, открывает файловый дескриптор для file.txt и в подцикле читает каждую строку в этом файле и записывает ее в STDOUT; повторное использование $_ в этом цикле нам пришлось временно сохранить его на шаге 2
  5. print $temp; записывает изначально прочитанную строку в STDOUT независимо от того, было ли найдено совпадение на шаге 3

Практический результат состоит в том, что каждая строка STDIN записывается в STDOUT, но если какая-либо строка содержит </body>, все содержимое file.txt вставляются до того, как эта строка будет записана.

Вы этого хотели? Если да, заверните его в find, перенаправление STDIN и STDOUT и переименование STDOUT поверх STDIN после выполнения остается для вас в качестве упражнения. Также следует отметить, что если у вас более одного случая </body> в вашем файле вы получите содержимое file.txt вставляется каждый раз, когда это происходит.