Є кілька способів вирішити цю проблему sed. Один із способів - відкладене читання, як рекомендується у прийнятій відповіді. Він також може бути записаний так:
sed -e '$!N;P;/\nPointer/r file1' -e D file2
... з невеликим явним поглядом наперед, а не задом, який реалізується в іншому місці з буфером утримування. Це неминуче матиме ті ж проблеми з останнім рядком, @don_crissti замітки, хоча, тому що N робить збільшення циклу лінії і rСвинець команда застосовується по номеру рядка.
Ви можете її обійти:
echo | sed -e '$d;N;P;/\nPointer/r file1' -e D file2 -
Не всі seds будуть інтерпретувати -середній стандартний вхід, але багато хто робить. ( POSIX каже, що sed має підтримувати -середнє значення стандартного входу, якщо реалізатор хоче -означати стандартне введення ???)
Інший спосіб - обробляти доданий вміст в порядку. Є ще одна команда, яка планує виводити так само, як rробить ead, і sedзастосовуватиме її та read у порядку, за яким вони написані. Але це трохи більше задіяно - це тягне за собою використання одного sedдля aдодавання Pointerвідповідності до виводу іншого sedу своєму сценарії.
sed ' /Pointer/!d #only operate on first match
s/[]^$&\./*[]/\\&/g;H #escape all metachars, Hold
s|.*|/&/!p;//!d|p;g #print commands, exchange
s|.|r file1&a\\&|;q' file2| #more commands, quit
sed -nf - file2 #same input file
Отже, в основному перший sedпише другий sedсценарій, який другий sedчитає на стандартному вході (можливо ...) і застосовується по черзі. Перший sedпрацює лише на першому збігу для Pointerзнайденого, а потім qвводить введення. Його завдання полягає в тому, щоб ...
s/[]^$&\./*[]/\\&/g;H
- Переконайтесь, що всі знаки шаблону надійно відхилені від косої риски, оскільки для другого
sedзнадобиться інтерпретувати буквально кожен біт, який він читає, щоб правильно його встановити. Як тільки це буде зроблено, покладіть копію в Hстарий простір.
s|.*|/&/!p;//!d|p; x
- Скажіть другому,
sedщоб pзаздалегідь накреслити кожен рядок введення, !окрім того, /&/який ми просто зафіксували за допомогою шаблону; а потім dвибирати все те саме. pвкажіть команди на другій sed, а потім xзмініть hстарі та буфери візерунків, щоб працювати над збереженою копією.
s|.|r file1&a\\&|p;q
- Єдиний
\nшарм, з яким ми працюємо тут, - це ewline, тому що він sedбуде попереджати його, коли ми Hпереносимо рядок раніше. Отже, ми вставляємо команду r file1і слідуємо за нею нашою \newline, потім команда a\\для append, а також \newline. Весь решта нашої Hлінії eld слідує за останньою \newline.
Сценарій, який пише перший, виглядає приблизно так:
/Pointer-file2 "23"/!p;//!d
r file1
a\
Pointer-file2 "23"
В основному другий sedбуде надрукувати кожен рядок, але той, який перший, sedвстановлює його на aдодаток. Для цього конкретного рядка заплановано два затримки запису до стандартного виходу - перший - це ead, а другий - це копія рядка, який ми хочемо після нього. Лікування першого лікаря в цьому випадку навіть не потрібно (див. «Відсутність косої риски»), але важливо безпечно бігти так, як я роблю тут, коли зміна шаблону замінюється як вхідний.rfile1sed
Так чи інакше, так ... є кілька способів.