Je veux supprimer quelques lignes n à la fin d'un fichier. Cela peut-il être fait avec sed?
Par exemple, pour supprimer les lignes 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 à la fin. S'il vous plaît laissez-moi savoir comment faire cela en utilisant sed ou une autre méthode.
Je ne sais pas à propos de sed
, mais cela peut être fait avec head
:
head -n -2 myfile.txt
Si le codage en dur n est une option, vous pouvez utiliser des appels séquentiels à sed. Par exemple, pour supprimer les trois dernières lignes, supprimez la dernière ligne trois fois:
sed '$d' file | sed '$d' | sed '$d'
De la 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 sed
et tac
amusante et simple:
n=4
tac file.txt | sed "1,$n{d}" | tac
REMARQUE
"
sont nécessaires pour que le shell puisse évaluer la variable $n
dans la commande sed
. Entre guillemets simples, aucune interpolation ne sera effectuée.tac
est une cat
inversée, voir man 1 tac
{}
dans sed
sont là pour séparer $n
& d
(sinon, le Shell tente d'interpoler une variable $nd
non existante)Utilisez sed
, mais laissez le shell faire le calcul, l'objectif étant 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 vers l’exté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, l'interprétation originale de sed après Shell est la suivante:
sed -i 2174,$d file
Avec -i
en cours de montage sur place, le fichier est maintenant 2173 lignes!
Vous pouvez utiliser head pour cela.
Utilisation
$ head --lines=-N file > new_file
où N est le nombre de lignes que vous souhaitez supprimer du fichier.
Le contenu du fichier original moins les N dernières lignes est maintenant dans new_file
Pour compléter, j’aimerais ajouter ma solution . J'ai fini par le faire avec la variable standard ed
:
ed -s sometextfile <<< $'-2,$d\nwq'
Ceci supprime les 2 dernières lignes en utilisant l'édition sur place (bien que utilise utilise un fichier temporaire dans /tmp
!!)
Pour tronquer des fichiers très volumineux réellement sur place, nous avons la commande truncate
. Elle ne connaît pas les lignes, mais tail
+ wc
peut convertir les lignes en octets:
file=bigone.log
lines=3
truncate -s -$(tail -$lines $file | wc -c) $file
Il existe 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 les octets à partir du début du fichier (mind disk IO), nous allons donc toujours tronquer limite de ligne (éventuellement plus de lignes que prévu si le fichier est écrit activement):
truncate -s $(head -n -$lines $file | wc -c) $file
One-liner pratique si vous échouez lors 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
Cela pourrait fonctionner pour vous (GNU sed):
sed ':a;$!N;1,4ba;P;$d;D' file
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 portable:
Perl -ne 'Push(@fifo,$_);print shift(@fifo) if @fifo > 10;'
OR
Perl -ne 'Push(@buf,$_);END{print @buf[0 ... $#buf-10]}'
OR
awk '{buf[NR-1]=$0;}END{ for ( i=0; i < (NR-10); i++){ print buf[i];} }'
Où "10" est "n".
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 ya 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 toucher EOF. Lorsque vous appuyez sur EOF, imprimez le contenu de l'espace de stockage et quittez.
sed -e '$!{N;N;N;N;N;N;H;}' -e x
La commande sed ci-dessus omettra les 5 dernières lignes.
Essayez la commande suivante:
n = line number
tail -r file_name | sed '1,nd' | tail -r
Cela peut être fait en 3 étapes:
a) Comptez le nombre de lignes du 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
Vous pouvez obtenir le nombre total de lignes avec wc -l <file>
et utiliser
head -n <total lines - lines to remove> <file>
Cela supprimera les 12 dernières lignes
sed -n -e :a -e '1,10!{P;N;D;};N;ba'
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//'
sed -n ':pre
1,4 {N;b pre
}
:cycle
$!{P;N;D;b cycle
}' YourFile
version posix
Je suis venu avec ceci, où n est le nombre de lignes que vous souhaitez 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.
Pour supprimer les N dernières lignes d’un fichier, vous pouvez utiliser le même concept de
$ sed '2,4d' file
Vous pouvez utiliser une commande combo avec queue pour inverser le fichier: si N vaut 5
$ tail -r file | sed '1,5d' file | tail -r > file
Et cette manière fonctionne aussi là où la commande head -n -5 file
ne s’exécute pas (comme sur un mac!).
Je préfère cette solution;
head -$(gcalctool -s $(cat file | wc -l)-N) file
oùNest le nombre de lignes à supprimer.