texto sustituir script reemplazar para linea insertar especiales espacios eliminar caracteres caracter blanco añadir linux bash shell sed

linux - sustituir - Cómo usar sed para eliminar las últimas n líneas de un archivo



sed shell (20)

Quiero eliminar algunas n líneas del final de un archivo. ¿Se puede hacer esto usando sed?

Por ejemplo, para eliminar líneas del 2 al 4, puedo usar

$ sed ''2,4d'' file

Pero no sé los números de línea. Puedo eliminar la última línea usando

$sed $d file

pero quiero saber la forma de eliminar n líneas del final. Por favor, hágamelo saber cómo usar sed o algún otro método.


Con las respuestas aquí, ya habrás aprendido que sed no es la mejor herramienta para esta aplicación.

Sin embargo, creo que hay una forma de hacer esto al usar sed; la idea es agregar N líneas para mantener el espacio hasta que puedas leer sin tocar EOF. Cuando se golpea EOF, imprima el contenido del espacio de espera y salga.

sed -e ''$!{N;N;N;N;N;N;H;}'' -e x

El comando sed de arriba omitirá las últimas 5 líneas.


De los sed one-liners :

# delete the last 10 lines of a file sed -e :a -e ''$d;N;2,10ba'' -e ''P;D'' # method 1 sed -n -e :a -e ''1,10!{P;N;D;};N;ba'' # method 2

Parece ser lo que estás buscando.


Esto eliminará las últimas 12 líneas

sed -n -e :a -e ''1,10!{P;N;D;};N;ba''


Esto eliminará las últimas 3 líneas del file :

for i in $(seq 1 3); do sed -i ''$d'' file; done;


Esto podría funcionar para usted (GNU sed):

sed '':a;$!N;1,4ba;P;$d;D'' file


La mayoría de las respuestas anteriores parecen requerir comandos / extensiones de GNU:

$ head -n -2 myfile.txt -2: Badly formed number

Para una solución ligeramente más portable:

perl -ne ''push(@fifo,$_);print shift(@fifo) if @fifo > 10;''

O

perl -ne ''push(@buf,$_);END{print @buf[0 ... $#buf-10]}''

O

awk ''{buf[NR-1]=$0;}END{ for ( i=0; i < (NR-10); i++){ print buf[i];} }''

Donde "10" es "n".


No sé sobre sed , pero se puede hacer con la head :

head -n -2 myfile.txt


Para eliminar las últimas 4 líneas:

$ nl -b a file | sort -k1,1nr | sed ''1, 4 d'' | sort -k1,1n | sed ''s/^ *[0-9]*/t//''


Para truncar realmente los archivos muy grandes, tenemos un comando truncate . No sabe sobre líneas, pero tail + wc puede convertir líneas en bytes:

file=bigone.log lines=3 truncate -s -$(tail -$lines $file | wc -c) $file

Existe una condición de carrera obvia si el archivo se escribe al mismo tiempo. En este caso, puede ser mejor usar head : cuenta los bytes desde el principio del archivo (mind disk IO), por lo que siempre truncaremos el límite en línea (posiblemente más líneas de lo esperado si el archivo está escrito activamente):

truncate -s $(head -n -$lines $file | wc -c) $file

Handy one-liner si no inicia sesión intente poner la contraseña en lugar del nombre de usuario:

truncate -s $(head -n -5 /var/log/secure | wc -c) /var/log/secure


Pruebe el siguiente comando:

n = line number tail -r file_name | sed ''1,nd'' | tail -r


Puede obtener el recuento total de líneas con wc -l <file> y usar

head -n <total lines - lines to remove> <file>


Puedes usar cabeza para esto.

Utilizar

$ head --lines=-N file > new_file

donde N es el número de líneas que desea eliminar del archivo.

El contenido del archivo original menos las últimas N líneas ahora está en new_file


Se me ocurrió esto, donde n es el número de líneas que desea eliminar:

count=`wc -l file` lines=`expr "$count" - n` head -n "$lines" file > temp.txt mv temp.txt file rm -f temp.txt

Es una pequeña rotonda, pero creo que es fácil de seguir.

  1. Cuente el número de líneas en el archivo principal
  2. Reste la cantidad de líneas que desea eliminar del recuento
  3. Imprima la cantidad de líneas que desea conservar y almacene en un archivo temporal
  4. Reemplace el archivo principal con el archivo temporal
  5. Eliminar el archivo temporal

Se puede hacer en 3 pasos:

a) Cuente el número de líneas en el archivo que desea editar:

n=`cat myfile |wc -l`

b) Resta de ese número el número de líneas para eliminar:

x=$((n-3))

c) Tell sed para eliminar de ese número de línea ( $x ) hasta el final:

sed "$x,/$d" myfile


Si hardcoding n es una opción, puede usar llamadas secuenciales a sed. Por ejemplo, para eliminar las últimas tres líneas, elimine la última línea tres veces:

sed ''$d'' file | sed ''$d'' | sed ''$d''


Solo para completar, me gustaría agregar mi solución. Terminé haciendo esto con la ed estándar:

ed -s sometextfile <<< $''-2,$d/nwq''

Esto borra las últimas 2 líneas usando la edición in situ (¡¡¡aunque utiliza un archivo temporal en /tmp !!)


Una solución graciosa y simple sed y tac :

n=4 tac file.txt | sed "1,$n{d}" | tac

NOTA

  • comillas dobles " son necesarias para que el shell evalúe la variable $n en el comando sed . En comillas simples, no se realizará la interpolación.
  • tac es un cat invertido, ver man 1 tac
  • {} in sed están ahí para separar $n & d (si no, el shell trata de interpolar la variable $nd no existente)

Usa sed , pero deja que el shell haga los cálculos, con el objetivo de usar el comando d dando un rango (para eliminar las últimas 23 líneas):

sed -i "$(($(wc -l < file)-22)),/$d" file

Para eliminar las últimas 3 líneas, de adentro hacia afuera:

$(wc -l < file)

Da el número de líneas del archivo: digamos 2196

Queremos eliminar las últimas 23 líneas, por lo que para el lado izquierdo o el rango:

$((2196-22))

Da: 2174 Por lo tanto, la interpretación original de sed tras capa es:

sed -i 2174,$d file

Con -i haciendo edit in place, ¡el archivo ahora tiene 2173 líneas!


Yo prefiero esta solución;

head -$(gcalctool -s $(cat file | wc -l)-N) file

donde N es el número de líneas para eliminar.


sed -n '':pre 1,4 {N;b pre } :cycle $!{P;N;D;b cycle }'' YourFile

posix versión