sed: elimina todas menos las últimas X líneas de un archivo

sed: elimina todas menos las últimas X líneas de un archivo

Se puede hacer con otras herramientas, pero me interesa saber cómo puedo eliminar todas menos las últimas X líneas del archivo con sed.

Respuesta1

Básicamente estás emulando la cola. X = 20 en este ejemplo. El siguiente ejemplo eliminará todas menos las últimas 20 líneas:

sed -i -e :a -e '$q;N;21,$D;ba' filename

Explicación:

  • El -e :a crea una etiqueta llamada a
  • La siguiente -e:
    • $q - sale e imprime el espacio del patrón si es la última línea
    • N - siguiente línea
    • 21,$D: ejecuta el comando "D" si el número de línea es >= 21 (21,$ = línea 21 hasta $ que es el final del archivo)
    • ba: ramas para etiquetar 'a', que es el comienzo del guión.

Respuesta2

sedEs bastante complejo cuando se trata de una tarea como ésta. tail, grepo awkharía esto mucho más fácil y debería usarse en su lugar. Dicho esto,esposible.

La siguiente solución está adaptada desed y búsqueda y reemplazo de varias líneas.

sed -ni '
    # if the first line copy the pattern to the hold buffer
    1h
    # if not the first line then append the pattern to the hold buffer
    1!H
    # if the last line then ...
    ${
            # copy from the hold to the pattern buffer
            g
            # delete current line if it is followed by at least X more lines
            # replace X-1 with the proper value
            s/.*\n\(\(.*\n\)\{X-1\}\)/\1/
            # print
            p
    }
' filename

Sin los comentarios, es una frase ingeniosa. Si desea eliminar, por ejemplo, todo excepto las últimas diez líneas, utilice esto:

sed -ni '1h;1!H;${;g;s/.*\n\(\(.*\n\)\{9\}\)/\1/;p;}' filename

Respuesta3

Basado en el guión desección 4.13 del manual sedpodrías hacer algo como esto:

n=10

(( n > 1 )) && script='1h; 2,'$n'{H;g;}; $q; 1,'$((n-1))'d; N; D'
(( n > 1 )) || script='$!d'

sed -i "$script" infile

Respuesta4

tac|sed|tac>&&(mv||gato>)

Los siguientes fragmentos de comando eliminarán efectivamente todos excepto los mismos.último5líneasde ~/file1. Si desea conservar elúltimo10líneas, puedes sustituir: |sed '1,5!d;'por |sed '1,10!d;',etcétera, como veas conveniente.

  1. tac ~/"file1" |sed '1,5!d;' |tac >"/tmp/file2" &&mv  "/tmp/file2"  ~/"file1"
  2. tac ~/"file1" |sed '1,5!d;' |tac >"/tmp/file2" &&cat "/tmp/file2" >~/"file1"

información relacionada