Є кілька способів вирішити цю проблему 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 -
Не всі sed
s будуть інтерпретувати -
середній стандартний вхід, але багато хто робить. ( POSIX каже, що sed
має підтримувати -
середнє значення стандартного входу, якщо реалізатор хоче -
означати стандартне введення ???)
Інший спосіб - обробляти доданий вміст в порядку. Є ще одна команда, яка планує виводити так само, як r
робить ead, і sed
застосовуватиме її та r
ead у порядку, за яким вони написані. Але це трохи більше задіяно - це тягне за собою використання одного 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
і слідуємо за нею нашою \n
ewline, потім команда a\\
для a
ppend, а також \n
ewline. Весь решта нашої H
лінії eld слідує за останньою \n
ewline.
Сценарій, який пише перший, виглядає приблизно так:
/Pointer-file2 "23"/!p;//!d
r file1
a\
Pointer-file2 "23"
В основному другий sed
буде надрукувати кожен рядок, але той, який перший, sed
встановлює його на a
додаток. Для цього конкретного рядка заплановано два затримки запису до стандартного виходу - перший - це ead, а другий - це копія рядка, який ми хочемо після нього. Лікування першого лікаря в цьому випадку навіть не потрібно (див. «Відсутність косої риски»), але важливо безпечно бігти так, як я роблю тут, коли зміна шаблону замінюється як вхідний.r
file1
sed
Так чи інакше, так ... є кілька способів.