Lo siguiente imprimirá la coincidencia de línea TERMINATE
hasta el final del archivo:
sed -n -e '/TERMINATE/,$p'
Explicado: -n
deshabilita el comportamiento predeterminado sed
de imprimir cada línea después de ejecutar su secuencia de comandos, -e
indicando una secuencia de comandos para sed
, /TERMINATE/,$
es una selección de rango de dirección (línea) que significa la primera línea que coincide con la TERMINATE
expresión regular (como grep) al final del archivo ( $
) , y p
es el comando de impresión que imprime la línea actual.
Esto se imprimirá desde la línea que sigue a la línea coincidente TERMINATE
hasta el final del archivo:
(DESPUÉS de la línea coincidente a EOF, SIN incluir la línea coincidente)
sed -e '1,/TERMINATE/d'
Explicado: 1,/TERMINATE/
es una selección de rango de dirección (línea) que significa la primera línea para la entrada a la primera línea que coincide con la TERMINATE
expresión regular, y d
es el comando de eliminación que elimina la línea actual y salta a la siguiente línea. Como sed
el comportamiento predeterminado es imprimir las líneas, imprimirá las líneas desde TERMINATE
el final de la entrada.
Editar:
Si quieres las líneas antes TERMINATE
:
sed -e '/TERMINATE/,$d'
Y si desea ambas líneas antes y después TERMINATE
en 2 archivos diferentes en una sola pasada:
sed -e '1,/TERMINATE/w before
/TERMINATE/,$w after' file
Los archivos antes y después contendrán la línea con terminación, por lo que para procesar cada uno debe usar:
head -n -1 before
tail -n +2 after
Edit2:
SI no desea codificar los nombres de archivo en el script sed, puede:
before=before.txt
after=after.txt
sed -e "1,/TERMINATE/w $before
/TERMINATE/,\$w $after" file
Pero luego debe escapar del $
significado de la última línea para que el shell no intente expandir la $w
variable (tenga en cuenta que ahora usamos comillas dobles alrededor del script en lugar de comillas simples).
Olvidé decir que la nueva línea es importante después de los nombres de archivo en el script para que sed sepa que los nombres de archivo terminan.
Editar: 2016-0530
Sébastien Clément preguntó: "¿Cómo reemplazarías el hardcoded TERMINATE
por una variable?"
Haría una variable para el texto coincidente y luego lo haría de la misma manera que en el ejemplo anterior:
matchtext=TERMINATE
before=before.txt
after=after.txt
sed -e "1,/$matchtext/w $before
/$matchtext/,\$w $after" file
para usar una variable para el texto coincidente con los ejemplos anteriores:
## Print the line containing the matching text, till the end of the file:
## (from the matching line to EOF, including the matching line)
matchtext=TERMINATE
sed -n -e "/$matchtext/,\$p"
## Print from the line that follows the line containing the
## matching text, till the end of the file:
## (from AFTER the matching line to EOF, NOT including the matching line)
matchtext=TERMINATE
sed -e "1,/$matchtext/d"
## Print all the lines before the line containing the matching text:
## (from line-1 to BEFORE the matching line, NOT including the matching line)
matchtext=TERMINATE
sed -e "/$matchtext/,\$d"
Los puntos importantes sobre la sustitución de texto con variables en estos casos son:
- Las variables (
$variablename
) encerradas en single quotes
[ '
] no se "expandirán" pero las variables dentro de double quotes
[ "
] sí. Por lo tanto, debe cambiar todo single quotes
a double quotes
si contienen texto que desea reemplazar con una variable.
- Los
sed
rangos también contienen una $
y son seguidos inmediatamente por una carta como: $p
, $d
, $w
. También se verá como las variables que ser ampliado, por lo que tiene que escapar de esos $
personajes con una barra invertida [ \
] como: \$p
, \$d
, \$w
.
grep 'TERMINATE' file