Existem algumas maneiras de fazer isso com sed
. Uma maneira é uma leitura atrasada, como é recomendado na resposta aceita. Também poderia ser escrito como:
sed -e '$!N;P;/\nPointer/r file1' -e D file2
... com um pouco de look-ahead explícito em vez do look-behind implementado em outro lugar com o buffer de espera. Isso inevitavelmente terá o mesmo problema com a última linha que @don_crissti observa, porque N
faz incrementar o ciclo de linha e o comando r
ead é aplicado por número de linha.
Você pode contornar isso:
echo | sed -e '$d;N;P;/\nPointer/r file1' -e D file2 -
Nem todos os sed
s interpretarão o -
para indicar a entrada padrão, mas muitos o fazem. ( POSIX diz sed
deve suportar -
para indicar o padrão se o implementador quiser -
para significar padrão-em ???)
Outra maneira é manipular o conteúdo acrescentado em ordem. Existe outro comando que agenda a saída da mesma maneira que r
ead, e sed
irá aplicá-lo e r
na ordem em que estão em script. Porém, é um pouco mais complicado - implica em usar uma sed
para a
ppend a correspondência Pointer
para a saída de outro sed
em seu script.
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
Então, basicamente o primeiro sed
escreve o segundo script sed
a, que o segundo sed
lê na entrada padrão (talvez ...) e aplica-se por sua vez. O primeiro sed
só funciona na primeira correspondência de Pointer
encontrado e depois q
uits de entrada. Seu trabalho é ...
-
%código%
- Certifique-se de que todos os chars padrão estejam com escape de barra invertida com segurança, porque o segundo
s/[]^$&\./*[]/\&/g;H
precisará interpretar cada bit literalmente para acertar. Feito isso, coloque uma cópia em sed
old space.
-
%código%
- Diga ao segundo
H
a s|.*|/&/!p;//!d|p; x
rint a cada linha de entrada sed
, mas a p
que acabamos de padronizar; e depois para !
elete tudo igual. /&/
rint os comandos no segundo d
, depois e p
alteram os buffers sed
old e padrão para trabalhar em nossa cópia salva.
-
%código%
- O único caractere com o qual trabalhamos aqui é um
x
ewline, porque h
terá um prepended quando s|.|r file1&a\&|p;q
da linha antes. Então, inserimos o comando \n
e o seguimos com o nosso sed
ewline, depois o comando H
para r file1
ppend seguido também por \n
ewline. Todo o restante de nossa linha a\
segue a última a
ewline.
O script que o primeiro escreve é parecido com isto:
/Pointer-file2 "23"/!p;//!d
r file1
a\
Pointer-file2 "23"
Basicamente, o segundo \n
imprime todas as linhas, mas a primeira H
configura para \n
ppend. Para essa linha em particular, duas gravações atrasadas para o padrão são programadas - a primeira é a sed
ead de sed
e a segunda é uma cópia da linha que quero depois disso. A primeira manipulação de a
nem é necessária neste caso (veja 'sem barras invertidas) mas é importante escapar com segurança da maneira que eu faço aqui sempre que uma correspondência de padrão é reaproveitada como entrada .
Enfim, então ... existem algumas maneiras.