¿Cómo elimino todas las líneas de un archivo que comienzan después de una línea coincidente?

84

Tengo un archivo que se compone de varias líneas de texto:

The first line
The second line
The third line
The fourth line

Tengo una cadena que es una de las líneas: The second line

Quiero eliminar la cadena y todas las líneas posteriores en el archivo, por lo que se eliminará The third liney The fourth lineademás de la cadena. El archivo se convertiría en:

The first line

He buscado una solución en Google y parece que debería usar sed. Algo como:

sed 'linenum,$d' file

Pero, ¿cómo encontrar el número de línea de la cadena? O, ¿de qué otra manera debería hacerlo?

DocWiki
fuente
Su declaración de problema es contradictoria: 'Quiero eliminar todas las líneas después de la línea' significa que elimina solo dos líneas (como dice), pero luego su salida de ejemplo muestra que la línea de coincidencia también falta. ¿Cuál quieres realmente?
Jonathan Leffler
La línea coincidente Y todas las líneas posteriores. Debería mejorar mi inglés. Gracias por tu información.
DocWiki
relacionado stackoverflow.com/questions/17364951/…
Trevor Boyd Smith

Respuestas:

136

Si no desea imprimir la línea coincidente (o las siguientes líneas):

sed -n '/The second line/q;p' inputfile

Esto dice "cuando llegue a la línea que coincide con el patrón, salga, de lo contrario imprima cada línea". La -nopción evita la impresión implícita y pse requiere el comando para imprimir líneas explícitamente.

o

sed '/The second line/,$d' inputfile

Esto dice "eliminar todas las líneas de la salida comenzando en la línea coincidente y continuando hasta el final del archivo".

pero el primero es más rápido. Sin embargo, dejará de procesar por completo, por lo que si tiene varios archivos como argumentos, los que están después del primer archivo coincidente no se procesarán. En este caso, el formulario de eliminación es mejor.

Si desea imprimir la línea coincidente, pero no las siguientes líneas:

sed '/The second line/q' inputfile

Esto dice "imprima todas las líneas y salga cuando se alcance la línea coincidente" (la -nopción (sin impresión implícita) no se usa).

Consulte man sed para obtener información adicional.

Pausado hasta nuevo aviso.
fuente
3
Pero algunos comandos se ponen ansiosos por las tuberías rotas (RCS, co -ppor ejemplo), y luego está mejor con la sed '/The second line/,$d'notación.
Jonathan Leffler
¿Puede agregar explicaciones?
Ahmad Abdelghany
@AhmadAbdelghany: Se agregaron explicaciones.
Pausado hasta nuevo aviso.
@DennisWilliamson Muchas gracias.
Ahmad Abdelghany
el primer método imprime la última línea antes de la línea coincidente dos veces. eliminar los trabajos pposteriores ;.
CrazyFrog
27

Esto es un poco más corto que otras soluciones dadas. Dejar de usar Q mayúscula evita imprimir la línea actual.

 sed '/The second line/Q' file

Para eliminar realmente las líneas, puede usar la misma sintaxis.

 sed -i '/The second line/Q' file
jaap
fuente
1
Esta es, con mucho, mi solución favorita.
Try TryAgain
5
sed '/The second line/q0' file

O, sin gnu sed:

sed '/The second line/q' file

O, usando grep:

grep -B 9999999 "The second line"
Erik
fuente
¡Muchas gracias! ¿Puede decirme cómo puedo encontrar el número de línea de una cadena específica, que todavía no sé?
DocWiki
grep -n Archivo "La segunda línea" | awk -F: '{print $ 1}'
Erik
@DocWiki: no necesita el número de línea; lo buscas. sed "/$string/,\$d" inputfile.
Jonathan Leffler
5

Usando awk (sin mostrar la línea coincidente)

awk '/pattern/ {exit} {print}' file.txt
Joel Arnold
fuente
Esta es la mejor respuesta, ya que es posible que no conozca el valor de la segunda línea.
RonJohn
0

Primero agregue el número de línea y elimine la línea

cat new.txt 
The first line
The second line
The third line
The fourth line

 cat new.txt  | nl
     1  The first line
     2  The second line
     3  The third line
     4  The fourth line



cat new.txt  | nl | sed  "/2/d"
     1  The first line
     3  The third line
     4  The fourth line

cat new.txt  |  nl |sed  "3d;4d"
     1  The first line
     2  The second line

usando awk

awk 'NR!=3 && NR!=4' new.txt 
The first line
The second line
sush
fuente
0
awk '/The second line/{exit}1' file
Kurumi
fuente