5 votes

sed : supprime toutes les lignes d'un fichier sauf les X dernières

Il est possible de le faire avec d'autres outils, mais je voudrais savoir comment supprimer toutes les lignes du fichier, à l'exception des X dernières, à l'aide de la fonction sed .

10voto

phiz Points 316

En fait, vous imitez la queue. X = 20 dans cet exemple. L'exemple suivant supprimera toutes les lignes sauf les 20 dernières :

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

Explication :

  • L'option -e :a crée une étiquette appelée a
  • Le -e suivant :
    • $q - quitte et imprime l'espace du motif s'il s'agit de la dernière ligne
    • N - ligne suivante
    • 21,$D - exécute la commande "D" si le numéro de ligne est >= 21 (21,$ = 21ème ligne jusqu'à $ qui est la fin du fichier)
    • ba - passe à l'étiquette 'a' qui est le début du script.

6voto

Dennis Points 46916

sed est assez complexe lorsqu'il s'agit d'une tâche comme celle-ci. tail , grep ou awk faciliterait grandement la tâche et devrait être utilisé à la place. Ceci étant dit, il est possible.

La solution suivante est adaptée de Recherche et remplacement en ligne et multiligne .

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

Sans les commentaires, il s'agit d'une belle phrase. Si vous voulez éliminer, par exemple, tout ce qui n'est pas les dix dernières lignes, utilisez ceci :

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

2voto

galeksic Points 121

Basé sur le script en section 4.13 du manuel sed vous pourriez faire quelque chose comme ça :

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

0voto

voices Points 2501

Tac|sed|tac>&&(mv||cat>)

Les deux extraits de commande suivants supprimeront effectivement toutes les données, à l'exception de celles qui se trouvent à l'extrême droite de l'écran. dernier 5 lignes de ~/file1 . Si vous souhaitez conserver le dernier 10 lignes Vous pouvez les remplacer par d'autres : |sed '1,5!d;' con |sed '1,10!d;' , et ainsi de suite comme vous l'entendez.

  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"

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X