Cat, Grep, Redirect Output… Fichier vierge?

8

Je viens de courir

cat /opt/webapplications/Word/readme.log | grep -v 'Apple'

et j'ai obtenu la sortie sur le cli que j'attendais, qui était toutes les lignes readme.logqui ne contenaient pas ' Apple' ...

Ensuite, j'ai couru ...

cat /opt/webapplications/Word/readme.log | grep -v 'Apple' > /opt/webapplications/Word/readme.log

Cependant, /opt/webapplications/Word/readme.logest vide.

Quelqu'un peut-il m'expliquer pourquoi cela s'est produit, ou la façon correcte dont j'aurais dû procéder?

Jeffrey L. Roberts
la source
stackoverflow.com/questions/6696842/…
aaaaa dit réintégrer Monica
1
vous essayez de lire et d'écrire le même fichier et les processus bash en premier (de droite à gauche)
aaaaa dit de rétablir Monica

Réponses:

14

Cela est arrivé parce que la première chose à >faire est de créer le fichier dans lequel il veut écrire - et si le fichier existe déjà, son contenu sera supprimé. (De plus, il n'est pas du tout nécessaire d'utiliser catdans votre déclaration, car il grepfonctionne sur des fichiers, pas seulement sur STDIN.)

La bonne façon de procéder consiste à utiliser un fichier temporaire pour lire ou pour écrire. Donc soit

cp /opt/webapplications/Word/readme.log /tmp/readme.log
grep -v 'Apple' /tmp/readme.log > /opt/webapplications/Word/readme.log

ou

grep -v 'Apple' /opt/webapplications/Word/readme.log > /tmp/readme.log
mv /tmp/readme.log /opt/webapplications/Word/readme.log

travaillerait.

Jenny D
la source
1

Lors d'une redirection vers le même fichier ( >), le shell peut créer / tronquer le fichier avant que la catcommande ne soit invoquée et que l'entrée ne soit lue (voir: Pourquoi «trier fichier1> fichier1» ne fonctionne pas? ). Si vous souhaitez filtrer le fichier, il est préférable de rediriger la sortie vers un fichier différent, ou d'éviter la redirection du tout, par exemple:

grep -v 'Apple' readme.log | tee readme.log

Le moyen le plus sûr et le plus sûr consiste à utiliser des éditeurs sur place conçus pour ce type d'opérations, par exemple

sed -i '.bak' '/Apple/d' readme.log

ou utiliser ex(partie de Vim):

ex +g/Apple/d -cwq readme.log

En relation:

kenorb
la source