Заменить строку содержимым файла, используя sed

23

У меня есть два разных файла:

File1

/home/user1/  
/home/user2/bin  
/home/user1/a/b/c

File2

<TEXT1>
<TEXT2>

Я хочу , чтобы заменить <TEXT1>из Файл2 с содержанием File1 использования sed. Я попробовал эту команду, но не получил правильный вывод:

cat File2|sed "s/<TEXT1>/$(cat File1|sed 's/\//\\\//g'|sed 's/$/\\n/g'|tr -d "\n")/g"

Вы можете использовать другие инструменты, чтобы решить эту проблему.

chanchal1987
источник
Пожалуйста, вставьте это сообщение об ошибке, чтобы мы могли найти его источник. Также скажите нам, какую sedреализацию вы используете. You код работает для меня с GNU sed.
manatwork
Извините, не получаю ошибку. Я не получаю желаемый результат. Выход как/home/user1/ n/home/user2/bin n/home/user1/a/b/cn <TEXT2> . Не получаю новых строк.
chanchal1987
Не уверен , если это будет применяться в вашем конкретном случае, но с diffи patchинструменты позволяют довольно легко заменить некоторые строки в файле другими линиями.
Стефан Гименес
1
Кстати, использование случайных данных, собранных с $()помощью сценария Sed, заставляет мои глаза кровоточить. Никогда не используйте внешние данные в местах, где некоторые символы интерпретируются с особым значением.
Стефан Хименес

Ответы:

24

Вот решение для сценария sed (на первый взгляд проще, чем попытаться поместить его в одну строку в командной строке):

/<TEXT1>/ {
  r File1
  d
}

Запуск это:

$ sed -f script.sed File2
/home/user1/
/home/user2/bin
/home/user1/a/b/c
<TEXT2>
Кусалананда
источник
Спасибо, это работает. Но я не хочу использовать любой другой файл сценария. Есть ли встроенное решение?
chanchal1987
Конечно:, sed '/<TEXT1>/{rFile1^Md^M}' File2где "^ M" вы нажимаете клавишу возврата. Проблема в том, что sed действительно нужны символы новой строки в {...} для разделения команд r и d.
Кусалананда
6
с bash строки в стиле posix немного чище:sed $'/<TEXT1>/ {r File1\n d}'
Гленн Джекман
9
Также с -e для одного вкладыша:sed -e '/<TEXT1>/{r File1' -e 'd}' File2
sdaau
1
А что, если вместо замены всей строки, содержащей <TEXT1>я, я просто хочу заменить саму строку, оставив остальную часть строки нетронутой? Text1: <TEXT1>к Text1: <file_contents>.
Робин Уинслоу
9

Мне потребовалось много времени, чтобы найти это решение с помощью замены var. Все решения Sed у меня не сработали, так как они либо удаляют полные строки, либо заменяют неправильно.

FILE2=$(<file2)
FILE1=$(<file1)
echo "${FILE2//TEXT1/$FILE1}" 

Заменяет все вхождения TEXT1 в file2 против содержимого file1. Весь остальной текст остается нетронутым.

marcas756
источник
очень хорошо. возможно быстрее, чем sedтоже, так как эти «расширения» (или замены) встроены в оболочку ( bashпо крайней мере)
желто-желтый
7

Я отвечаю, потому что метод diff/ patchможет быть интересен в некоторых случаях. Чтобы определить замену строк, содержащихся в файле blob1, строками, содержащимися в blob2использовании:

diff -u blob1 blob2 > patch-file

Например, если blob1содержит:

hello
you

и blob2содержит:

be
welcome
here

сгенерированный patch-fileбудет:

--- blob1   2011-09-08 16:42:24.000000000 +0200
+++ blob2   2011-09-08 16:50:48.000000000 +0200
@@ -1,2 +1,3 @@
-hello
-you
+be
+welcome
+here

Теперь вы можете применить этот патч к любому другому файлу:

patch somefile patch-file

Он заменит hello, youлинии от be, welcome, hereлинии в somefile.

Стефан Хименес
источник
это действительно умно, но было бы лучше, если бы вы могли автоматизировать это с помощью сценария
qodeninja