Замініть багаторядковий рядок у файлах


17

У мене є кілька файлів, які я хочу оновити, замінивши один багаторядковий рядок на інший багаторядковий рядок. Щось у напрямку:

* Some text, 
* something else
* another thing

І я хочу замінити його на:

* This is completely
* different text

Результатом було б те, що після заміни файл, що містить перший блок тексту, тепер буде містити другий рядок (решта файлу залишається незмінною).

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

Чи є простий спосіб це зробити? Sed - це варіант, але це незручно, тому що я повинен додати \ n і т. Д. Чи є спосіб сказати "взяти вхід з цього файлу, зіставити його в цих файлах, а потім замінити його вмістом цього іншого файлу"? Я можу використовувати python за потреби, але я хочу щось швидке і просте, тому, якщо є утиліта, я скоріше скористаюся цим, ніж напишу свій власний сценарій (який я знаю, як зробити).


Напевно, ви повинні використовувати perl для цього. stackoverflow.com/questions/1030787/…
orion

3
Отже, ви хочете відповідати, some text, something else another thingчи охоплює він чи кілька ліній? Або ви хочете лише відповідати some text,\nsomething else\nanotherthing?
mikeserv

2
Відредагуйте своє запитання та уточніть, який саме вміст кожного файлу (файлів) та який потрібний вихід.
jimmij

Рядок охоплює кілька рядків. Я швидше ігнорую пробіли при зіставленні / заміні, тому що це може бути не абсолютно однаковим, але це не є великою справою, якщо я просто виконаю матч 1-1 (нові рядки та всі).
Венців

Відповіді:


12

Замініть "Some ... \ n ... Thing" вмістом файлу "new" в одному або декількох вхідних файлах

perl -i -p0e 's/Some.*?thing\n/`cat new`/se' input.txt ...
  1. -i безпосередньо змінити input.txt
  2. -p0 розбийте файл вхідного файлу та роздрукуйте його в кінці
  3. s/regexp/.../s в regexp .є.|\n
  4. s/.../exp/e замінити на eval(exp)
  5. new - файл, що містить текст заміни (Це повністю ... інший текст)
  6. якщо корисно, ви можете розширити оригінальний текст s/Some text\n...\n...thing\n/...

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

@Kvothe, нам потрібні додаткові деталі ... Припустимо, що "раніше" не має спеціальних символів, ви можете спробуватиperl -i -p0e ' $b= `cat before`; s/$b/Some thing\n/se' input.txt ...
JJoao

І якщо припустити, що "до" містить усі спеціальні символи (нові рядки, косі риски, дужки), крім "та".
Квоте

5
sed -e :n -e '$!N;/\n.*\n/!{$!bn
};  s/some text,\n* *something else\n* *another thing/this is completely\
different text/;P;D' <infile

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

Він повинен мати можливість відповідати рядку, чи охоплює він кілька рядків чи ні - до трьох, тобто. Але немає жодних положень щодо відображення цього положення в заміні - воно завжди охоплює два рядки, як написано.


0

Не сильний (тому що не чечуйте другу строку, але це легко вирішити), і це може бути не компілятором posix, а дуже простим:

sed '/^Some text/{:1;/another thing$/!{N;b 1}
     s/.*/this is completely\ndifferent text/g}' input.txt

Перша команда додає рядки з деякого тексту, поки не зустрінеться інша річ, потім другий рядок зміни її на інший текст.

ПРИМІТКА Обмеження полягає в тому деяким текстом завжди повинна дотримуватися інша річ .


Проблема полягає в тому, що рядок може містити більше 2 рядків (до десятка або більше) і може містити інші речі, які, можливо, знадобиться вийти, наприклад, вкладки, * тощо.
ventsyv

@ventsyv Немає проблеми з кількістю рядків або роздільниками - скрипт перевіряє лише початок і кінець. Цілком достатньо, якщо початковий рядок може exeptionally позначати текст для зміни . Якщо немає кращого, покажіть приклад введення для створення правильного шаблону.
Костас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.