Comment utiliser sed pour supprimer les n dernières lignes d'un fichier
Je veux supprimer certaines lignes n de la fin d'un fichier. Cela peut-il être fait en utilisant sed?
Par exemple, pour supprimer des lignes de 2 à 4, je peux utiliser
$ sed '2,4d' file
Mais je ne connais pas les numéros de ligne. Je peux supprimer la dernière ligne en utilisant
$sed $d file
Mais je veux savoir comment supprimer N lignes de la fin. Veuillez me faire savoir comment le faire en utilisant sed ou une autre méthode.
20 réponses
Je ne connais pas sed
, mais cela peut être fait avec head
:
head -n -2 myfile.txt
À partir des sed one-liners :
# delete the last 10 lines of a file
sed -e :a -e '$d;N;2,10ba' -e 'P;D' # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba' # method 2
Semble être ce que vous recherchez.
Une solution drôle et simple sed
et tac
:
n=4
tac file.txt | sed "1,$n{d}" | tac
NOTE
- les guillemets doubles
"
sont nécessaires pour que le shell évalue la variable$n
dans la commandesed
. Guillemets simples, aucune interpolation sera effectuée. -
tac
est uncat
inversé, voirman 1 tac
- Les
{}
dans {[1] } sont là pour séparer$n
&d
(si ce n'est pas le cas, le shell essaie d'interpoler la variable inexistante$nd
)
Si le codage en dur n est une option, vous pouvez utiliser des appels séquentiels vers sed. Par exemple, pour supprimer les trois dernières lignes, supprimez la dernière ligne trois fois:
sed '$d' file | sed '$d' | sed '$d'
Utilisez sed
, mais laissez le shell faire le calcul, dans le but d'utiliser la commande d
en donnant une plage (pour supprimer les 23 dernières lignes):
sed -i "$(($(wc -l < file)-22)),\$d" file
Pour supprimer les 3 dernières lignes, de l'intérieur:
$(wc -l < file)
Donne le nombre de lignes du fichier: dire 2196
Nous voulons supprimer les 23 dernières lignes, donc pour le côté gauche ou la plage:
$((2196-22))
Donne: 2174 Ainsi, le sed original après l'interprétation du shell est:
sed -i 2174,$d file
Avec -i
faire place éditer le fichier est maintenant 2173 les lignes!
Vous pouvez utiliser tête pour ce.
Utiliser
$ head --lines=-N file > new_file
Où N est le nombre de lignes que vous souhaitez supprimer du fichier.
Le contenu du fichier d'origine moins les N dernières lignes sont maintenant dans new_file
Juste pour l'exhaustivité, je voudrais ajouter ma solution.
J'ai fini par le faire avec la norme ed
:
ed -s sometextfile <<< $'-2,$d\nwq'
Cela supprime les 2 dernières lignes en utilisant l'édition sur place (bien que utilise un fichier temporaire dans /tmp
!!)
Cela pourrait fonctionner pour vous (GNU sed):
sed ':a;$!N;1,4ba;P;$d;D' file
Pour tronquer de très gros fichiers vraiment en place, Nous avons la commande truncate
.
Il ne connaît pas les lignes, mais tail
+ wc
peut convertir des lignes en octets:
file=bigone.log
lines=3
truncate -s -$(tail -$lines $file | wc -c) $file
Il y a une condition de concurrence évidente si le fichier est écrit en même temps.
Dans ce cas, il peut être préférable d'utiliser head
- il compte des octets depuis le début du fichier (mind disk IO), donc nous allons toujours tronquer sur la limite de la ligne (peut-être plus de lignes que prévu si le fichier est activement écrit):
truncate -s $(head -n -$lines $file | wc -c) $file
Une doublure pratique si vous échec de la tentative de connexion en mettant le mot de passe à la place du nom d'utilisateur:
truncate -s $(head -n -5 /var/log/secure | wc -c) /var/log/secure
Avec les réponses ici, vous auriez déjà appris que sed n'est pas le meilleur outil pour cette application.
Cependant, je pense qu'il existe un moyen de le faire en utilisant sed; l'idée est d'ajouter N lignes pour conserver l'espace jusqu'à ce que vous puissiez lire sans frapper EOF. Lorsque EOF est activé, imprimez le contenu de l'espace d'attente et quittez.
sed -e '$!{N;N;N;N;N;N;H;}' -e x
La commande sed ci-dessus omettra les 5 dernières lignes.
La plupart des réponses ci-dessus semblent nécessiter des commandes/extensions GNU:
$ head -n -2 myfile.txt
-2: Badly formed number
Pour une solution légèrement plus portible:
perl -ne 'push(@fifo,$_);print shift(@fifo) if @fifo > 10;'
Ou
perl -ne 'push(@buf,$_);END{print @buf[0 ... $#buf-10]}'
Ou
awk '{buf[NR-1]=$0;}END{ for ( i=0; i < (NR-10); i++){ print buf[i];} }'
Où "10" est "n".
Essayez la commande suivante:
n = line number
tail -r file_name | sed '1,nd' | tail -r
Vous pouvez obtenir le nombre total de lignes avec wc -l <file>
et utiliser
head -n <total lines - lines to remove> <file>
Cela peut être fait en 3 étapes:
A) comptez le nombre de lignes dans le fichier que vous souhaitez modifier:
n=`cat myfile |wc -l`
B) soustrayez de ce nombre le nombre de lignes à supprimer:
x=$((n-3))
C) dites à sed de supprimer de ce numéro de ligne ($x
) jusqu'à la fin:
sed "$x,\$d" myfile
Je préfère cette solution;
head -$(gcalctool -s $(cat file | wc -l)-N) file
Où N est le nombre de lignes à supprimer.
sed -n ':pre
1,4 {N;b pre
}
:cycle
$!{P;N;D;b cycle
}' YourFile
Version Posix
Pour supprimer les 4 dernières lignes:
$ nl -b a file | sort -k1,1nr | sed '1, 4 d' | sort -k1,1n | sed 's/^ *[0-9]*\t//'
Je suis venu avec ceci, où n est le nombre de lignes que vous voulez supprimer:
count=`wc -l file`
lines=`expr "$count" - n`
head -n "$lines" file > temp.txt
mv temp.txt file
rm -f temp.txt
C'est un petit rond-point, mais je pense que c'est facile à suivre.
- Comptez le nombre de lignes dans le fichier principal
- soustrayez le nombre de lignes que vous souhaitez supprimer du nombre
- affiche le nombre de lignes que vous souhaitez conserver et stocker dans un fichier temporaire
- remplacez le fichier principal par le fichier temporaire
- supprimer le fichier temporaire
Cela permettra d'éliminer les 3 dernières lignes de file
:
for i in $(seq 1 3); do sed -i '$d' file; done;
Cela supprimera les 12 dernières lignes
sed -n -e :a -e '1,10!{P;N;D;};N;ba'