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