Hay algunas maneras de hacer esto con / sed
. Una forma es una lectura retrasada como se recomienda en la respuesta aceptada. También podría escribirse como:
sed -e '$!N;P;/\nPointer/r file1' -e D file2
... con un poco de anticipación explícita en lugar de la retrospectiva implementada en otros lugares con el búfer de retención. Sin embargo, eso inevitablemente tendrá el mismo problema con la última línea que @don_crissti observa, ya N
que incrementa el ciclo de la línea y el r
comando ead se aplica por número de línea.
Puedes evitarlo:
echo | sed -e '$d;N;P;/\nPointer/r file1' -e D file2 -
No todos los sed
s interpretarán el -
significado de entrada estándar, pero muchos lo hacen. ( POSIX dice que sed
debería admitir la entrada -
estándar estándar si el implementador quiere -
decir entrada estándar ???)
Otra forma es manejar el contenido agregado en orden. Hay otro comando que programa la salida de la misma manera que r
ead, y la sed
aplicará y r
ead en el orden en que están escritas. Sin embargo, es un poco más complicado: implica usar uno sed
para a
agregar la Pointer
coincidencia a la salida de otro sed
en su 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
Entonces, básicamente, el primero sed
escribe el segundo sed
un script, que el segundo sed
lee en entrada estándar (tal vez ...) y se aplica a su vez. El primero sed
solo funciona en la primera coincidencia para Pointer
encontrado, y luego q
ingresa. Su trabajo es ...
s/[]^$&\./*[]/\\&/g;H
- Asegúrese de que todos los caracteres del patrón tengan una barra invertida sin escape porque el segundo
sed
tendrá que interpretar cada bit que lee literalmente para hacerlo bien. Una vez hecho esto, coloque una copia en el H
espacio antiguo.
s|.*|/&/!p;//!d|p; x
- Dígale al segundo
sed
que p
borre cada línea de entrada, !
excepto la /&/
que acabamos de guardar con patrones; y luego d
elegir todo lo mismo. p
borre los comandos en el segundo sed
, luego x
cambie los h
búferes antiguos y de patrones para que funcionen en nuestra copia guardada.
s|.|r file1&a\\&|p;q
- El único
\n
personaje con el que trabajamos aquí es un ewline porque sed
habrá antepuesto uno cuando H
eludimos la línea antes. Entonces, insertamos el comando r file1
y lo seguimos con nuestra línea \n
electrónica, luego el comando a\\
para a
ppend seguido también por una línea \n
electrónica. Todo el resto de nuestra H
línea de campo sigue esa última \n
línea.
El guión que escribe el primero se parece a esto:
/Pointer-file2 "23"/!p;//!d
r file1
a\
Pointer-file2 "23"
Básicamente, el segundo sed
imprimirá cada línea, pero la primera la sed
configurará para a
pasar. Por esa particular línea de dos escrituras con retraso a la salida estándar están programados - el primero es el r
ead de file1
y el segundo es una copia de la línea que queremos después de ella. El primer sed
cuidado no es necesario en este caso (¿ve? No hay barras invertidas) pero es importante escapar de manera segura como lo hago aquí cada vez que una coincidencia de patrón se reutiliza como entrada.
De todos modos, entonces ... hay algunas maneras.