Considerar:
echo -e "a\nb\nc\nd\ne\nf\ng\nh" | sed '3,5a test'
Esto coincidirá con las líneas 3, 4 y 5.
Pero estoy tratando de hacer coincidir solo las líneas 3 y 5 (no 4). Y agregue 'prueba' después de ellos.
Considerar:
echo -e "a\nb\nc\nd\ne\nf\ng\nh" | sed '3,5a test'
Esto coincidirá con las líneas 3, 4 y 5.
Pero estoy tratando de hacer coincidir solo las líneas 3 y 5 (no 4). Y agregue 'prueba' después de ellos.
Respuestas:
echo ... | sed -e '3a test' -e '5a test'
Si la operación es más compleja que en este caso, puede usar una estructura como esta:
sed 'b pattern; : action; a \
lalala
b end; : pattern; 3b action; 5b action; : end'
Es decir, pones todos los comandos que necesitas entre b pattern;
y b end;
.
Y agrega todos sus patrones (números de línea o lo que sea) después : pattern;
.
Lo que pasa es esto:
El primer comando salta sobre la parte de acción (tal vez sea más fácil de leer si los patrones están al principio y b end;
directamente antes de la parte de acción).
Si un patrón coincide, la ejecución salta a la parte de acción. Después de la acción, la ejecución de la parte salta al final.
Intento arreglar esto:
sed '3b action; 5b action; b end; : action; a \
lalala
: end'
En una sola línea sería como:
sed "3b idAction; 5b idAction; b; : idAction; a test"
Portablemente, necesitas escribirlo:
sed '
3b action
5b action
b
: action
a\
lalala'
( b
sin ramas de etiqueta hasta el final, por lo que no necesita una end
etiqueta explícita , ;
es válido un carácter en una etiqueta en sed
implementaciones estándar ).
Con sed
(ver la respuesta de @ HaukeLaging )
Con awk
:
$ echo -e "a\nb\nc\nd\ne\nf\ng\nh" | awk 'NR==3 || NR==5{$0=$0"\ntest"}1;'
Con perl
:
$ echo -e "a\nb\nc\nd\ne\nf\ng\nh" | perl -pe '$_ .="test\n" if $. == 3 || $. == 5'
perl -lnE 'say if $. ~~ @{[3,5]}'
~~
, no lo entiendo tan bien como debería. Además, ambos say
y ~~
necesitan perl v> = 5.10 ¿verdad?
perl -pE 'say "test" if $. ~~ @{[4,6]}'
- esto antepone la línea: perl's -p
hace una impresión implícita al final del programa dado.
Como @HaukeLaging aleady dijo, este comando hace lo que quiere:
sed -e'3a test' -e'5a test'
Ahora, esto puede resultar bastante engorroso de escribir si desea hacer coincidir, por ejemplo, 20 líneas.
En estos casos, suponiendo que su shell sea compatible con la expansión de llaves , puede usar este comando en su lugar:
sed -e{3,5}'a test'
(Tenga en cuenta que los corchetes y la coma deben permanecer sin comillas).
Como resultado, la cáscara se pasan los argumentos para -e3a test
y -e5a test
con sed, que es exactamente lo que hace el primer comando.