En raison d'un bug d'application non encore diagnostiqué, j'ai plusieurs centaines de serveurs avec un disque plein. Il y a un fichier qui a été rempli de lignes en double - pas un fichier journal, mais un fichier d'environnement utilisateur avec des définitions de variables (donc je ne peux pas simplement supprimer le fichier).
J'ai écrit une sed
commande simple pour vérifier les lignes ajoutées par erreur et les supprimer, et je l'ai testée sur une copie locale du fichier. Cela a fonctionné comme prévu.
Cependant, lorsque je l'ai essayé sur le serveur avec le disque plein, j'ai eu environ l'erreur suivante (c'est de la mémoire, pas de copier-coller):
sed: couldn't flush /path/to/file/sed8923ABC: No space left on deviceServerHostname
Bien sûr, je sais qu'il n'y a plus d'espace. C'est pourquoi j'essaie de supprimer des trucs! (La sed
commande que j'utilise réduira un fichier de plus de 4000 lignes à environ 90 lignes.)
Ma sed
commande est justesed -i '/myregex/d' /path/to/file/filename
Existe-t-il un moyen d'appliquer cette commande malgré le disque plein?
(Il doit être automatisé, car je dois l'appliquer à plusieurs centaines de serveurs comme solution rapide.)
(Évidemment, le bogue d'application doit être diagnostiqué, mais en attendant, les serveurs ne fonctionnent pas correctement ....)
Mise à jour: La situation à laquelle j'ai été confrontée a été résolue en supprimant quelque chose d'autre que j'ai découvert que je pouvais supprimer, mais j'aimerais toujours la réponse à cette question, qui serait utile à l'avenir et pour d'autres personnes.
/tmp
est un non-go; c'est sur le même système de fichiers.
Avant de libérer de l'espace disque, j'ai testé et découvert que je pouvais supprimer les lignes en vi
ouvrant le fichier et en l'exécutant :g/myregex/d
, puis en enregistrant avec succès les modifications avec :wq
. Il semble qu'il devrait être possible d'automatiser cela, sans avoir recours à un système de fichiers distinct pour contenir un fichier temporaire .... (?)
sed -i
crée une copie temporaire pour fonctionner. Je soupçonne que ce ed
serait mieux pour cela, bien que je ne sois pas assez familier pour proscrire une solution réelle
ed
vous couriez: printf %s\\n g/myregex/d w q | ed -s infile
mais gardez à l'esprit que certaines implémentations utilisent également des fichiers temporaires comme sed
(vous pouvez essayer busybox ed - afaik ne crée pas de fichier temporaire)
echo
. utiliser printf
. et faites sed
ajouter quelques caractères que vous déposez à la dernière ligne pour éviter de perdre des blancs de fin. De plus, votre shell doit être capable de gérer l'intégralité du fichier sur une seule ligne de commande. c'est votre risque - testez d'abord. bash
est particulièrement mauvais à cela (je pense que c'est à faire avec un espace de pile?) et peut vous fatiguer à tout moment. les deux sed
'si recommandés utiliseraient au moins le tampon de pipe du noyau pour faire bon effet entre eux, mais la méthode est assez similaire. votre sous-commande commandera également file
si le sed w / in réussit ou non.
sed '/regex/!H;$!d;x' <file|{ read v && cat >file;}
et si cela fonctionne, lisez le reste de ma réponse.