web-dev-qa-db-fra.com

En face de la queue: toutes les lignes sauf les n dernières lignes

Comment puis-je supprimer les n dernières lignes d'un fichier avec un filtre de ligne de commande unix?

Ce serait en quelque sorte l'opposé de tail: tail ignore les n premières lignes mais laisse passer le reste, mais je souhaite que la commande dirige tout à l'exception des n dernières lignes.

Malheureusement, je n'ai rien trouvé de tel - head ne m'aide pas non plus. EDIT: au moins sous Solaris, les arguments ne sont pas négatifs.

Mise à jour: je suis surtout intéressé par une solution qui fonctionne pour les gros fichiers, comme les fichiers journaux, dans laquelle vous pourriez vouloir inspecter ce qui s’est passé au cours des dernières minutes.

32
Hans-Peter Störr

Si vous avez GNU head, vous pouvez utiliser

head -n -5 file.txt

imprimer toutes les lignes sauf les 5 dernières de file.txt.

Si head -n ne prend aucun argument négatif, essayez

head -n $(( $(wc -l file.txt | awk '{print $1}') - 5 )) file.txt
37
user570500

Voici un moyen simple de supprimer la dernière ligne, qui fonctionne sous BSD, etc.

sed '$d' input.txt

L'expression lit "sur la dernière ligne, supprimez-le". Les autres lignes seront imprimées car il s'agit du comportement par défaut de sed.

Vous pouvez les chaîner pour supprimer plusieurs lignes

sed '$d' input.txt | sed '$d' | sed '$d'

Ce qui est un peu lourd, certes, mais ne fait qu’analyser le fichier.

Vous pouvez également y jeter un coup d'œil pour plus de réponses: https://stackoverflow.com/questions/13380607/how-to-use-sed-to-remove-last-n- lignes-de-fichier

Voici un one-liner adapté de l'un de mes favoris:

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

Je me suis amusé à déchiffrer celui-ci, et j'espère que vous aussi. (: Il met en mémoire tampon les lignes N lorsqu’il scanne, mais c’est plutôt efficace.

5
jwd
head file.txt               # first 10 lines
tail file.txt               # last 10 lines
head -n 20 file.txt         # first 20 lines
tail -n 20 file.txt         # last 20 lines
head -20 file.txt           # first 20 lines
tail -20 file.txt           # last 20 lines
head -n -5 file.txt         # all lines except the 5 last
tail -n +5 file.txt         # all lines except the 4 first, starts at line 5
4
Kjetil S.

Je suis curieux de savoir pourquoi vous pensez que head n'est pas une option:

~$ man head
...
-n, --lines=[-]K
        print the first K lines instead of the first 10; 
        with the leading `-', print all but the last K lines of each file

Cela semble correspondre à votre objectif, en utilisant, par exemple:

head -n -20 yourfile.txt
3
Anders R. Bystrup

Une autre façon de le faire si tail -n ne prend pas d’arguments négatifs est

tac file.txt | tail -n +6 | tac

Cela supprimerait les 5 dernières lignes

0
atw31337