J'essaye de garder les 50 dernières lignes dans mon fichier où j'économise la température toutes les minutes. J'ai utilisé cette commande:
tail -n 50 /home/pi/Documents/test > /home/pi/Documents/test
Mais le résultat est un fichier de test vide. J'ai pensé, il listera les 50 dernières lignes du fichier de test et l'insérera dans le fichier de test. Lorsque j'utilise cette commande:
tail -n 50 /home/pi/Documents/test > /home/pi/Documents/test2
ça marche bien. Il y a 50 lignes dans le fichier test2.
Quelqu'un peut-il m'expliquer où est le problème?
command-line
logs
tail
dorinand
la source
la source
logging
moduleRéponses:
Le problème est que votre shell configure le pipeline de commandes avant d'exécuter les commandes. Ce n'est pas une question "d'entrée et de sortie", c'est que le contenu du fichier a déjà disparu avant même que tail ne s'exécute. Cela va quelque chose comme:
>
fichier de sortie pour l'écriture, le tronquanttail
.tail
court, s'ouvre/home/pi/Documents/test
et n'y trouve rienIl existe différentes solutions, mais la clé est de comprendre le problème, ce qui ne va pas et pourquoi.
Cela produira ce que vous cherchez,
Explication:
$()
est appelé substitution de commandes qui exécutetail -n 50 /home/pi/Documents/test
> /home/pi/Documents/test
redirige la sortie deecho "$(tail -n 50 /home/pi/Documents/test)"
vers le même fichier.la source
bash: xrealloc: cannot allocate 18446744071562067968 bytes
Une autre solution pour la redirection de fichiers effaçant le fichier en premier est d'utiliser
sponge
lemoreutils
pack comme ceci:la source
En effet, bash traite la redirection avec la
>
première, en supprimant le contenu du fichier. Il exécute ensuite la commande. Si vous l'utilisiez>>
, les 50 dernières lignes seraient ajoutées à la fin de ce qui se trouve actuellement dans le fichier. Dans ce cas, vous auriez les mêmes 50 lignes répétées deux fois.La commande fonctionne comme prévu lors de la redirection vers un fichier différent. Voici une façon d'écrire les 50 dernières lignes d'un fichier dans un fichier du même nom:
Cela écrit d'abord les 50 dernières lignes dans un fichier temporaire, qui est ensuite déplacé en utilisant
mv
pour remplacer le fichier d'origine.Comme indiqué dans les commentaires, cela ne fonctionnera pas si le fichier est toujours ouvert. Le déplacement du fichier crée également un nouvel inode et peut changer la propriété et les autorisations. Une meilleure façon de le faire en utilisant un fichier temporaire serait:
Le fichier temporaire peut également être supprimé, mais chaque fois que cela se produit, son contenu sera écrasé.
la source
tail -50 /home/pi/Documents/test >/tmp/foo && cat /tmp/foo >/home/pi/Documents/test
tail ... > temp ; cat temp > orig ; rm -f temp
travaux.Puisque vous avez vu le principal problème avec la redirection du shell, voici une autre façon de tailler un fichier à ses 50 dernières lignes:
Le travail acharné est effectué par (GNU) sed avec la fonction
-i
"édition sur place", qui fonctionne sous les couvertures en créant la sortie dans un fichier temporaire. Le reste des lignes a établi les mathématiques pour le fonctionnement de sed, à savoir:wc
), puis soustraire 50; assigner cela àn
.n
est positif, exécutez la commande sed pour supprimer les lignes 1 à n.la source
printf
est utilisé pour diriger les commandes (une par ligne) versed
. Lesed
commandes sont les suivantes:1,$-50d
- supprimer toutes les lignes sauf les 50 dernièresw
- réécrire le fichier modifié sur le disqueAucune redirection n'est impliquée, le shell ne peut donc pas écraser le fichier de sortie avant sa lecture.
De plus, contrairement à la plupart des formes d'édition "sur place" (qui ne simulent généralement que l'édition "sur place" en créant un fichier temporaire puis en le renommant par rapport à l'original),
ed
modifie en fait le fichier d'origine - il conserve donc le même inode ( et propriétaire, groupe et autorisations - tempfile + mv changera toujours l'inode, et peut changer les autres selon les circonstances).la source
Sur une piste légèrement différente, vous pouvez utiliser
logrotate(8)
pour sauvegarder régulièrement les fichiers journaux dans des fichiers nommés de manière incrémentielle, puis supprimer les anciens.C'est ainsi que les principaux fichiers journaux du système sont gérés pour éviter qu'ils ne s'allongent trop longtemps.
la source