Existe-t-il un moyen (ligne de commande POSIX) d’imprimer tout un fichier SAUF les n dernières lignes? Le cas d’utilisation étant, j’aurai plusieurs fichiers de taille inconnue, qui contiennent tous un pied de page standard de taille connue que je veux supprimer. Je me demandais s'il existait déjà un utilitaire qui le fait avant de l'écrire moi-même.
La plupart des versions de head (1) - GNU dérivé, en particulier, mais pas dérivé de BSD - ont une fonctionnalité permettant de le faire. Il montrera le haut du fichier sauf la fin si vous utilisez un nombre négatif pour le nombre de lignes à imprimer.
Ainsi:
head -n -10 textfile
Probablement moins efficace que la méthode "wc" + "faire le calcul" + "queue", mais plus facile à regarder:
tail -r file.txt | tail +NUM | tail -r
Où NUM
est égal à un de plus que le nombre de lignes de fin à supprimer, par exemple. +11 imprimera toutes les lignes sauf les 10 dernières. Cela fonctionne sur BSD qui ne supporte pas la syntaxe head -n -NUM
.
L'utilitaire head
est votre ami.
De la page de manuel de 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
Il n'y a pas de commande standard pour le faire, mais vous pouvez utiliser awk ou sed pour remplir un tampon deNlignes et imprimer à partir de la tête une fois pleine. Par exemple. avec awk:
awk -v n=5 '{if(NR>n) print a[NR%n]; a[NR%n]=$0}' file
cat <filename> | head -n -10 # Everything except last 10 lines of a file
cat <filename> | tail -n +10 # Everything except 1st 10 lines of a file
C'est simple. Vous devez ajouter + au nombre de lignes que vous souhaitez éviter.
Cet exemple vous donne toutes les lignes sauf les 9 premières
tail -n +10 inputfile
(oui, pas les 10 premiers ... parce que ça compte différemment ... si vous voulez 10, tapez juste tail -n 11 inputfile)
Si le pied de page commence par une ligne cohérente n'apparaissant pas ailleurs, vous pouvez utiliser sed
:
sed '/FIRST_LINE_OF_FOOTER/q' filename
Cela imprime la première ligne du pied de page; si vous voulez éviter cela:
sed -n '/FIRST_LINE_OF_FOOTER/q;p' filename
Cela pourrait être plus robuste que de compter les lignes si la taille du pied de page change à l'avenir. (Ou il pourrait être moins robuste si la première ligne change.)
Une autre option, si la commande head
de votre système ne prend pas en charge head -n -10
, consiste à précalculer le nombre de lignes à afficher. Les éléments suivants dépendent de la syntaxe spécifique à bash:
lines=$(wc -l < filename) ; (( lines -= 10 )) ; head -$lines filename
Notez que la syntaxe head -NUMBER
est prise en charge par certaines versions de head
pour des raisons de compatibilité ascendante. POSIX n'autorise que la forme head -n NUMBER
. De plus, POSIX n'autorise que l'argument à -n
à être un entier décimal positif; head -n 0
n'est pas nécessairement un no-op.
Une solution compatible POSIX est:
lines=$(wc -l < filename) ; lines=$(($lines - 10)) ; head -n $lines filename
Si vous devez utiliser d'anciennes coques pré-POSIX, vous pouvez envisager ceci:
lines=`wc -l < filename` ; lines=`expr $lines - 10` ; head -n $lines filename
N'importe lequel d'entre eux pourrait faire des choses étranges si un fichier compte 10 lignes ou moins.
tac fichier.txt | queue + [n + 1] | tac
Cette réponse est similaire à celle de user9645, mais elle évite la commande tail -r, qui n'est également pas une option valide pour de nombreux systèmes. Voir, par exemple, https://ubuntuforums.org/showthread.php?t=1346596&s=4246c451162feff4e519ef2f5cb1a45f&p=8444785#post8444785 pour un exemple.
Notez que le +1 (entre parenthèses) était nécessaire sur le système que je l’ai essayé, mais il n’est peut-être pas nécessaire sur votre système. Donc, pour supprimer la dernière ligne, je devais mettre 2 entre parenthèses. Cela est probablement lié au fait que la dernière ligne doit se terminer par un ou plusieurs caractères de saut de ligne réguliers. Ceci, sans doute, rend la dernière ligne une ligne vide. Si vous ne le faites pas, la commande tac combinera les deux dernières lignes. Par conséquent, la suppression de la "dernière" ligne (ou de la première à la fin de la commande) supprimera en réalité les deux dernières lignes.
Ma réponse devrait également être la solution la plus rapide parmi celles répertoriées à ce jour pour les systèmes ne disposant pas de la version améliorée de head. Je pense donc que c’est à la fois la réponse la plus robuste et la plus rapide.