Замініть рядок вмістом файлу за допомогою sed


23

У мене є два різних файли:

Файл1

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

Файл2

<TEXT1>
<TEXT2>

Я хочу , щоб замінити <TEXT1>з файл2 з вмістом File1 використання sed. Я спробував цю команду, але не отримав належного результату:

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

Ви можете використовувати й інші інструменти для вирішення цієї проблеми.


Будь ласка, вставте це повідомлення про помилку, щоб ми могли знайти його джерело. Також скажіть, яку саме sedфункцію ви використовуєте. Ваш код працює для мене з GNU sed.
манатура

Вибачте, не отримую помилку. Я не отримую бажаного результату. Вихід такий /home/user1/ n/home/user2/bin n/home/user1/a/b/cn <TEXT2>. Не отримує нових рядків.
chanchal1987

Не впевнений, чи застосовуватиметься це у вашому конкретному випадку, але за допомогою diffта patchінструменти дозволяють досить легко замінити деякі рядки у файлі іншими рядками.
Стефан Гіменез

1
Btw, використовуючи випадкові дані, зібрані $()за сценарієм 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" ти натискаєш return. Проблема полягає в тому, що sed дійсно потребує нових рядків у межах {...} для розмежування команд r та d.
Kusalananda

6
з bash, рядки в стилі posix трохи чистіші:sed $'/<TEXT1>/ {r File1\n d}'
glenn jackman

9
Також з для одного лайнера: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. Весь інший текст залишається недоторканим.


дуже хороша. можливо швидше, ніж 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.