Arguments négatifs en tête / queue

14

Des variantes de cette question ont certainement été posées plusieurs fois à différents endroits, mais j'essaie de supprimer les dernières Mlignes d'un fichier sans chance.

La deuxième réponse la plus votée dans cette question recommande de procéder comme suit pour se débarrasser de la dernière ligne d'un fichier:

head -n -1 foo.txt > temp.txt

Cependant, lorsque j'essaye cela dans OSX & Zsh, j'obtiens:

head: illegal line count -- -1

Pourquoi donc? Comment supprimer les M dernières lignes et les premières N lignes d'un fichier donné?

Amelio Vazquez-Reina
la source
1
Quelle est la sortie de head --version? Quel système utilisez-vous?
jofel
@jofel head --versionrenvoie en fait une erreur.
Amelio Vazquez-Reina

Réponses:

20

Vous pouvez supprimer les 12 premières lignes avec:

tail -n +13

(Cela signifie imprimer à partir de la 13e ligne.)

Quelques implémentations de support headGNU comme head:

head -n -12

mais ce n'est pas standard.

tail -r file | tail -n +12 | tail -r

fonctionnerait sur les systèmes qui ont tail -r(voir aussi GNU tac) mais n'est pas optimal.

nest 1:

sed '$d' file

Vous pouvez également faire:

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

pour supprimer 2 lignes, mais ce n'est pas optimal.

Tu peux faire:

sed -ne :1  -e 'N;1,12b1' -e 'P;D'

Mais attention, cela ne fonctionnera pas avec de grandes valeurs de n avec certaines sedimplémentations.

Avec awk:

awk -v n=12 'NR>n{print line[NR%n]};{line[NR%n]=$0}'

Pour supprimer des mlignes du début et nde la fin:

awk -v m=6 -v n=12 'NR<=m{next};NR>n+m{print line[NR%n]};{line[NR%n]=$0}'
Stéphane Chazelas
la source
sed 'x;1d;$d'peut également être utilisé pour obtenir les deux dernières lignes. Et avec quelques Naprès 1dpourrait être utilisé pour obtenir un peu plus que cela, bien qu'à ce stade, il n'offre aucun avantage sur la N;P;Dboucle que vous recommandez déjà.
mikeserv
Merci - La dernière commande est extrêmement utile. Une petite mise en garde estivale: cela ne fonctionne pas quand mou nsont 0. Sinon, ce serait parfait.
Amelio Vazquez-Reina
2

Vous pouvez utiliser la méthode suivante pour supprimer les N premières lignes et les M dernières lignes.

Avec N=5, M=7et le fichier test.txt:

sed -n -e "6,$(($(wc -l < test.txt) - 7))p" test.txt

La commande imprime toutes les lignes de N + 1 à LastLine-M.

Une autre option consiste à utiliser python:

python -c 'import sys;print "".join(sys.stdin.readlines()[5:-7]),' < test.txt
jofel
la source
1

Vous pouvez supprimer les dernières Mlignes (ici M = 100) d'un fichier avec:

head -$(($(wc -l < foo.txt) - 100)) foo.txt > temp.txt
faire
la source