Замініть шаблон у файлі зі вмістом іншого файлу


20

У мене є текстовий файл ( devel.xml).

Я додав до нього слово REPLACETHIS, щоб замінити цей рядок вмістом в іншому файлі ( temp.txt).

Найближче у мене це:

sed -i -e "/REPLACETHIS/r temp.TXT" -e "s///" devel.txt;

Це вставляє вміст після рядка, а потім видаляє рядок після цього.

Це найкращий спосіб зробити це?


Чи треба це сідати? Залежно від кількості тексту в temp.txt, я можу піднятися до рішення Perl.
користувач17591

Відповіді:


34

Те, що ви зробили, - це видалити, SUBSTITUTETHISде б він не з’явився у файлі (але не решту рядка, де він з’явився) і вставити вміст temp.TXTнижче цього рядка. Якщо SUBSTITUTETHISна рядку відображається кілька разів, видаляється лише перше явище, і temp.TXTдодається лише одна копія .

Якщо ви хочете замінити весь рядок, коли SUBSTITUTETHISз'явиться, скористайтеся dкомандою. Оскільки вам потрібно запустити і те, rі інше, dколи є відповідність, поставте їх у групу, встановлену фігурами.

sed -e '/SUBSTITUTETHIS/ {' -e 'r temp.TXT' -e 'd' -e '}' -i devel.txt

Деякі реалізації sed дозволяють використовувати крапки з комою для розділення команд та пропуску роздільників взагалі навколо дужок, але для завершення аргументу в rкоманді все ж потрібен новий рядок :

sed -e '/SUBSTITUTETHIS/ {r temp.TXT
                          d}' -i devel.txt

Якщо ви хочете замінити SUBSTITUTETHISвміст файлу, але зберегти те, що йде до і після нього у рядку, це складніше. Найпростіший метод - включити вміст файлу в команду sed; зауважте, що вам доведеться правильно цитувати його вміст.

sed -e "s/SUBSTITUTETHIS/$(<temp.TXT sed -e 's/[\&/]/\\&/g' -e 's/$/\\n/' | tr -d '\n')/g" -i devel.txt

Або скористайтеся Perl. Це коротко, але працює catодин раз для кожної заміни:

perl -pe 's/SUBSTITUTETHIS/`cat temp.TXT`/ge' -i devel.txt

Щоб прочитати файл один раз при запуску скрипту, і уникати, залежно від команди оболонки:

perl -MFile::Slurp -pe 'BEGIN {$r = read_file("temp.TXT"); chomp($r)}
                        s/SUBSTITUTETHIS/$r/ge' -i devel.txt

(представлено у двох рядках для читабельності, але ви можете опустити розрив рядка). Якщо ім'я файлу є змінним, щоб уникнути проблем із котируванням, передайте його до сценарію через змінну середовища:

replacement_file=temp.TXT perl -MFile::Slurp -pe 'BEGIN {$r = read_file($replacement_file); chomp($r)}
                        s/SUBSTITUTETHIS/$r/ge' -i devel.txt

Як я міг змінити команду perl, щоб замість цього cat temp.txtя міг це зробити cat ${variable}?
Марія Інес Парнісарі

@MariaInesParnisari Я помилився з форматуванням коментарів. Дивіться мою відповідь із дещо іншим, більш надійним рішенням.
Жил 'SO- перестань бути злим'

Оскільки File :: Slurp не завжди встановлюється, альтернативою є використання -0777перемикача на slurp у всьому файлі та звичайного open:perl -0777 -pe 'BEGIN {open F, q(temp.TXT); $r=<F>; chomp($r)} s/SUBSTITUTETHIS/$r/ge' -i devel.txt
mivk

Як обгортати r temp.TXTповідомлення типу "BEGIN temp.TXT", "END temp.TXX"
kyb

Я знайшов рішення для свого питання. Використовувати a(додати) команду. grymoire.com/Unix/Sed.html#uh-36
kyb
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.