# \[bash\] find avec execution en fonction d'un test

**URL:** <https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791>\
**Category:** Programmation\
**Created:** [Février 21, 2016, 2:57 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791 "2016-02-21T14:57:57Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![nonobecane](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/n/85f322/32.png) [@nonobecane](https://www.debian-fr.org/u/nonobecane)\
**Post date:** [Février 21, 2016, 2:57 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/1 "2016-02-21T14:57:57Z")

</div>

Bonjour à tous,

Je voudrais compresser des fichiers avec gzip uniquement s’il ne sont pas déjà compressé.

Pour être plus explicite, le logiciel Blender permet d’enregistrer et lire ces fichiers compressé avec gzip mais en maintenant l’extension \*.blend.

Mes fichiers blend étant relativement nombreux et lourds, je souhaite les compresser dans mon circuit de sauvegarde.

J’ai fait le script suivant :

`1 #!/bin/bash
2
3 ## déplacement dans le fichier de sauvegarde
4 cd /mnt/SAVE
5
6 ## recherche récursive des fichiers blend et compression gzip
7 find -name \*.blend -exec gzip {} +
8
9 ## recherche récursive des fichier blend.gz précedement créer et renommage en fichier blend
10 find . -name "*.blend.gz" -exec rename -v 's/\.blend.gz$/\.blend/i' {} \;`

Le problème est que je peux recompresser des fichiers ayant déjà été compressé.

Je souhaiterais donc tester au préablable les fichiers pour savoir s’il sont déjà compressé au format gzip.

J’imaginais pouvoir remplacer la ligne 7 de mon script par cette ligne :

```auto

```

mais la réponse de “gzip-l” étant du type “gzip: test.blend: not in gzip format” lorsque le fichier n’est pas déjà compressé, les “$0” de ma ligne ne fonctionne évidemment pas.

Auriez-vous une idée ?  
Je ne suis pas doué en script, j’ai glané sur le net pour en arriver là tout seul et maintenant je sèche

Merci de vos retours

Bon WE

---

<div class="post-metadata">

**Author:** ![anon29980398](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/f4b2a3/32.png) [@anon29980398](https://www.debian-fr.org/u/anon29980398)\
**Post date:** [Février 21, 2016, 2:58 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/2 "2016-02-21T14:58:02Z")

</div>

La piste “magique” :

Faire un :

```auto

```

et lire…  
Puis faire un :

```auto

```

et lire…

Puis voir ce que donne la commande “file -bi” ci-dessous:

`michel@deb-quad:~$ file -bi Documents/mes_blender/exemple-non-compacté.blend 
application/octet-stream; charset=binary
michel@deb-quad:~$ file -bi Documents/mes_blender/exemple-compacté.blend 
application/x-gzip; charset=binary
`

---

<div class="post-metadata">

**Author:** ![nonobecane](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/n/85f322/32.png) [@nonobecane](https://www.debian-fr.org/u/nonobecane)\
**Post date:** [Février 21, 2016, 2:58 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/3 "2016-02-21T14:58:03Z")

</div>

Merci de ton interet MicP,

Pour être sûr, on parle bien de magic : magic — file command’s magic pattern file  
et non du paquet magic : magic - VLSI layout editor ?

En tout les cas il va falloir que je regarde à tête reposé car à première vue, je ne sais pas exploiter la réponse “application/gzip; charset=binary” dans mon script de recherche pour qu’il ne compresse pas les fichiers ayant cette réponse.

Merci encore

---

<div class="post-metadata">

**Author:** ![anon29980398](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/f4b2a3/32.png) [@anon29980398](https://www.debian-fr.org/u/anon29980398)\
**Post date:** [Février 21, 2016, 2:58 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/4 "2016-02-21T14:58:03Z")

</div>

Oui: je parlais bien de "magic : magic — file command’s magic pattern file"  
Je ne suis qu’un autodidacte, donc, je programme pas forcément comme il faut, aussi j’espère que des personnes plus compétentes pourront nous aider pour la deuxième question:  
comment exploiter la réponse “application/gzip; charset=binary”.

Je serais tenté d’utiliser simplement cette chaîne de caractère dans une comparaison d’égalité dont le résultat conditionnerait la compression du fichier.  
À première vue il faudrait créer une fonction qui va être appelée par le “-exec” de la ligne #7 de ton script.  
je vais faire quelques recherches et des tests pour voir si je dis pas trop de bêtises

---

<div class="post-metadata">

**Author:** ![nonobecane](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/n/85f322/32.png) [@nonobecane](https://www.debian-fr.org/u/nonobecane)\
**Post date:** [Février 21, 2016, 2:58 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/5 "2016-02-21T14:58:04Z")

</div>

> [@MicP](#):
>
> Je ne suis qu’un autodidacte

Pas mieux, voir même moins 🙂 .

> [@MicP](#):
>
> Je serais tenté d’utiliser simplement cette chaîne de caractère dans une comparaison d’égalité dont le résultat conditionnerait la compression du fichier.

C’est ce à quoi j’avais pensé au départ, mais je ne sais pas intégré des «&nbsp;if&nbsp;» dans la commande find.  
Peut-être en effet en appelant un second script avec le exec.

Aujourd’hui j’ai un peu trop de retard à rattraper pour m’y consacrer. Donc désolé de ne pas être plus actif.

Merci encore de ton interet et bonne recherche

---

<div class="post-metadata">

**Author:** ![anon29980398](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/f4b2a3/32.png) [@anon29980398](https://www.debian-fr.org/u/anon29980398)\
**Post date:** [Février 21, 2016, 2:58 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/6 "2016-02-21T14:58:05Z")

</div>

EDIT (à ceux qui passeront par là plus tard):  
Dans ce post, on peux voir que je me suis tellement concentré sur le problème de test par “file -ib”, que j’en ai oublié de bien contrôler l’action (rename …)  
De plus, je n’ai pas pris assez de temps pour me renseigner sur la commande “find”, et j’ai tenté d’utiliser la variable $(FICHIER) là ou un “%h/” aurait été bien plus efficace.  
RESULTAT:  
l’affichage par “echo” était à première vue correct, mais à première vue seulement…  
et l’exécution de la commande “rename” à mis le désordre dans les fichiers à traiter.  
TOUJOURS VÉRIFIER ET TOUJOURS FAIRE DES TESTS AVANT DE LANCER SUR LE RÈEL  
FIN DE L’EDIT

Et ça, qu’est-ce que ça donne ?  
(j’ai n’ai laissé qu’un “echo “${FICHIER}”” pour les tests et commenté la commande qu’il suffira de dé-commenter si tout va bien)

[code]#!/bin/bash

# le dossier des sauvegardes

CHEMIN\_SAVE="/mnt/SAVE"

# (le “” en fin de ligne permet de “couper” la ligne de commande en plusieurs)

# rechercher les fichiers “.blend” et créer une liste avec un nom de fichier par ligne ("\n"),

# puis renvoyer cette liste par un “pipe” ("|") vers la commande suivante.

find “${CHEMIN\_SAVE}” -name \*.blend -printf “${CHEMIN\_SAVE}/”%f\n | \

# lire la liste de lignes créée par “find”

while read FICHIER  
do  
# Est-ce bien un fichier “.blend” qui n’a pas encore été compacté par “gzip” ?  
[[$( file -ib “${FICHIER}” ) != “application/x-gzip; charset=binary”]] &&   
{  
# compresser et renommer le fichier  
echo “${FICHIER}”  
#gzip “${FICHIER}” && rename -v ‘s/.blend.gz$/.blend/i’ “${FICHIER}”;  
};  
done;[/code]  
EDITxxx:  
je viens de tomber sur ça:  
[softpanorama.org/Tools/Find/ … find.shtml](http://www.softpanorama.org/Tools/Find/using_exec_option_and_xargs_in_find.shtml)  
je crois que je vais y trouver ce qu’il te faut, il ne me reste plus qu’à lire, tester, et assimiler…  
A+

---

<div class="post-metadata">

**Author:** ![nonobecane](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/n/85f322/32.png) [@nonobecane](https://www.debian-fr.org/u/nonobecane)\
**Post date:** [Février 21, 2016, 2:58 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/7 "2016-02-21T14:58:08Z")

</div>

Wouah!!  
Ça dépasse largement mes compétences

le : `echo "${FICHIER}"`  
Ressort bien la liste récursive des fichier blend sauf ceux déjà compressé.

Par contre quand je décommente la commande, le script compresse uniquement les fichiers blend de la racine, les autres affiche l’erreur : «&nbsp;gzip: /mnt/SAUVEGARDE/test/Exemple/modelisation.blend: No such file or directory&nbsp;»

Et pour ceux de la racine qui sont compressé, la commande «&nbsp;rename&nbsp;» ne semble pas fonctionner, les fichiers reste en .blend.gz

En tout cas merci beaucoup, car déjà vu le retour de la commande echo, je pense que la solution est on ne peux plus proche ![:041](https://www.debian-fr.org/uploads/default/original/1X/bfe857c9119752799c3eac55ca37a50312c51282.gif "applaudit")

---

<div class="post-metadata">

**Author:** ![anon29980398](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/f4b2a3/32.png) [@anon29980398](https://www.debian-fr.org/u/anon29980398)\
**Post date:** [Février 21, 2016, 2:58 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/8 "2016-02-21T14:58:13Z")

</div>

pour le problème de renommage et de racine, je suis allé un peu vite, et j’aurais dû vérifier un peu mieux ce que je postais.  
En fait, il suffisait de remplacer la ligne:  
gzip “${FICHIER}” && rename -v ‘s/.blend.gz$/.blend/i’ “${FICHIER}”;  
par:  
gzip “${FICHIER}” && mv “${FICHIER}.gz” “${FICHIER}”;  
(j’ai corrigé cette ligne plus tard après avoir lu le post suivant)

Pour le problème correspondant au message: “gzip: /mnt/SAUVEGARDE/test/Exemple/modelisation.blend: No such file or directory”:  
Pourtant, ici : ${CHEMIN\_SAVE}/"%f je spécifie bien que le chemin absolu soit transmis, de plus, l’affichage (juste “echo” sans dé-commenter la commande) serait correct.  
Il reste la possibilité que le chemin spécifié dans la variable “CHEMIN\_SAVE” ne soit pas un chemin absolu, mais comme tu me poste: “gzip: /mnt/SAUVEGARDE/test/Exemple/modelisation.blend: No such file or directory”, je vois bien que le chemin commence à la racine, et du coup, je vois pas du tout ce qui pourrait empêcher “gzip” de faire son travail.

---

<div class="post-metadata">

**Author:** ![nonobecane](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/n/85f322/32.png) [@nonobecane](https://www.debian-fr.org/u/nonobecane)\
**Post date:** [Février 21, 2016, 2:58 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/9 "2016-02-21T14:58:15Z")

</div>

Oups une petite correction :  
gzip “${FICHIER}” && mv “${FICHIER}.gz” “${FICHIER}”;

Pour les sous répertoire c’est de ma faute, mon exmeple n’était pas explicite :  
En fait pour le fichier “/mnt/SAVE/travail/test.blend"  
et pour : CHEMIN\_SAVE=”/mnt/SAVE"  
le message d’erreur est : gzip: /mnt/SAVE/test.blend: No such file or directory

En fait il ne prend pas en compte le chemin complet et les raccrochent à la racine. Aucun soucis pour ceux qui se trouve effectivement à la racine.

J’ai essayé avec gzip -r mais sans plus. Je pense que $FICHIER devrait contenir l’arborescence complète et dans ce cas, peut-être supprimer $CHEMIN\_SAVE.

Pour info, chez moi j’ai remplacé application/x-gzip; charset=binary par application/gzip; charset=binary  
C’est ce que me retourne la commande file -bi sur les fichiers concerné

Merci

---

<div class="post-metadata">

**Author:** ![anon29980398](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/f4b2a3/32.png) [@anon29980398](https://www.debian-fr.org/u/anon29980398)\
**Post date:** [Février 21, 2016, 2:58 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/10 "2016-02-21T14:58:17Z")

</div>

Désolé pour les erreurs, j’espère que ça n’a pas trop créé de désordre dans tes fichiers, quoique en voyant que tu avais utilisé un sous-dossier nommé “test”, je suppose que tu avais eu la sagesse de faire des essais avant de lancer le script.

Pour le chemin, je comprends mieux ce qui se passe :  
Un extrait du man de find :  
"%f Nom du fichier, sans aucun nom de répertoire (dernier élément uniquement)."

Toujours dans le man de “find” :  
"%h Répertoires en tête du nom de fichier (tout sauf la dernière partie). Si le nom du fichier ne contient aucune barre oblique (NDT : slash) (donc si c’est un fichier du répertoire courant), alors l’option %h rajoutera « . »."

Donc, il faudrait remplacer la ligne:

```auto

```

par:

```auto

```

======================  
D’autre part, en faisant un man gzip, j’ai pu me rendre compte qu’il est possible de réduire la dernière ligne de commande, en utilisant l’option “-c”.

`-c --stdout --to-stdout
              Write output on standard output; keep original files unchanged. If there are several input files, the
              output consists of a sequence of independently compressed members. To obtain better compression, con‐
              catenate all input files before compressing them.`  
En deux mots, on peux rediriger le flux de sortie de gzip vers un fichier en utilisant le caractère "\>"  
la ligne de commande :

```auto

```

peut donc être remplacée par:

```auto

```

Ça fait toujours un “mv” en moins…  
Mais je suis certain qu’il doit être possible de faire mieux, ne serait-ce qu’au sujet des “;” en trop, et de bien d’autres choses que ne ne vois pas.  
Ah! si un vrais programmeur pouvais passer par là…

---

<div class="post-metadata">

**Author:** ![nonobecane](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/n/85f322/32.png) [@nonobecane](https://www.debian-fr.org/u/nonobecane)\
**Post date:** [Février 21, 2016, 2:58 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/11 "2016-02-21T14:58:24Z")

</div>

Un grand Merci à toi Micp,  
C’est toi qui à fait tout le boulot.

Au final la version qui fonctionne : [code]#!/bin/bash

# le dossier des sauvegardes

CHEMIN\_SAVE="/tmp"

# (le “” en fin de ligne permet de “couper” la ligne de commande en plusieurs)

# rechercher les fichiers “.blend” et créer une liste avec un nom de fichier par ligne ("\n"),

# puis renvoyer cette liste par un “pipe” ("|") vers la commande suivante.

find “${CHEMIN\_SAVE}” -name \*.blend -printf %h/%f\n | \

# lire la liste de lignes créée par “find”

while read FICHIER  
do  
# Est-ce bien un fichier “.blend” qui n’a pas encore été compacté par “gzip” ?  
[[$( file -ib “${FICHIER}” ) != “application/gzip; charset=binary”]] &&   
{  
# compresser et renommer le fichier  
#echo "${FICHIER}"  
gzip “${FICHIER}” && mv “${FICHIER}.gz” “${FICHIER}”;  
};  
done;  
[/code]

J’ai conservé la commande de gzip avec le mv, car celle avec gzip -c crée des fichiers vides.  
J’ai tenté de remplacé`gzip -c "${FICHIER}" > "${FICHIER}";`par`gzip -c "${FICHIER}" >> "${FICHIER}";` mais la commande ne s’arrête pas et Gzip consomme du CPU. Après 2,3 minutes et un CTRL-C, un seul fichier .blend (le premier du repertoire) est malgré tout bel et bien compressé.

En tout cas bravo à toi ça fonctionne impec.  
A charge de revanche, si je peux t’aider sur autre chose

---

<div class="post-metadata">

**Author:** ![anon29980398](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/f4b2a3/32.png) [@anon29980398](https://www.debian-fr.org/u/anon29980398)\
**Post date:** [Février 21, 2016, 2:58 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/12 "2016-02-21T14:58:25Z")

</div>

Je te remercie beaucoup pour ton message.

Pour la dernière commande, je pense qu’il aurait fallu plutôt utiliser un «&nbsp;pipe&nbsp;» car réécrire sur un fichier qu’on lit n’est pas très bon, même si j’avais pas compris pourquoi ça fonctionnait chez moi, j’avais trouvé la solution bien pratique, mais  
gzip «&nbsp;${FICHIER}&nbsp;» && mv «&nbsp;${FICHIER}.gz&nbsp;» «&nbsp;${FICHIER}&nbsp;»  
est effectivement bien plus propre.

> [@nonobecane](#):
>
> A charge de revanche, si je peux t’aider sur autre chose

Oh que oui, j’aurais sûrement bientôt besoin de tes compétences vu que le fait d’avoir redémarré blender m’a donné envie de m’y remettre, mais il y a si longtemps,  
il faut juste que je prenne le temps de me remettre dans le bain, et à jour.

En tout cas, ça aura été un plaisir de pouvoir faire ce chemin avec toi, et j’en aurais beaucoup appris sur la commande «&nbsp;find&nbsp;» que je n’utilise pratiquement pas, et d’autres subtilités du bash qu’il me reste à apprendre.

Bonne journée et à bientôt.

---

<div class="post-metadata">

**Author:** ![nonobecane](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/n/85f322/32.png) [@nonobecane](https://www.debian-fr.org/u/nonobecane)\
**Post date:** [Février 21, 2016, 2:58 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/13 "2016-02-21T14:58:25Z")

</div>

> [@](#):
>
> j’aurais sûrement bientôt besoin de tes compétences vu que le fait d’avoir redémarré blender m’a donné envie de m’y remettre

Avec plaisir, je commence à me débrouiller avec blender, tu peux me trouver à ce sujet sur [http://blenderclan.tuxfamily.org](http://blenderclan.tuxfamily.org) et n’hésite surtout pas par MP.

A la prochaine ![:023](https://www.debian-fr.org/uploads/default/original/1X/3c587556c0cc11389317c03a60788d77ceebd307.gif "OK")

---

<div class="post-metadata">

**Author:** ![anon29980398](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/f4b2a3/32.png) [@anon29980398](https://www.debian-fr.org/u/anon29980398)\
**Post date:** [Février 21, 2016, 2:58 UTC](https://www.debian-fr.org/t/bash-find-avec-execution-en-fonction-dun-test/57791/14 "2016-02-21T14:58:27Z")

</div>

Le temps de reprendre un peu en main blender qui a beaucoup évolué (ma machine aussi…), de fouiller dans la doc et les tuto, de lire un peu tout ça et de bien définir ce que je veux faire avec en espérant pouvoir rédiger mes questions aussi bien que tu l’a fait ici.  
Je vais commencer par suivre le lien que tu m’a transmis.  
À bientôt.
