Commande find sous condition

Commande find sous condition - Codes et scripts - Linux et OS Alternatifs

Marsh Posté le 11-07-2012 à 09:56:33    

Bonjour,
j essaie de faire un find mais je n y arrive pas.
 
Je souhaite effacer tous les fichiers de type "nfo" qui sont seuls dans un dossier.
 
Exemple :
ls /tmp/folder1
toto.nfo
tata.txt
=> Ne doit donc pas etre supprimé
 
ls /tmp/folder2
toto2.nfo
=> Doit etre supprimer.
 
Apres faut aussi supprimer les dossiers vides mais ca c est pas un soucis, un rmdir * suffit !


---------------
=-Galerie Photo=- // Tekilaz :: Trop bon, Trop con... // FEEDB4CK
Reply

Marsh Posté le 11-07-2012 à 09:56:33   

Reply

Marsh Posté le 11-07-2012 à 11:53:44    

Compte les fichiers qui ne sont pas en nfo, et si il n'y en a pas, tu supprimes. Quelques chose du genre

 
Code :
  1. [[ $(ls | grep -v "nfo$" | wc -l) -eq 0 ]] && rm *nfo


ou mieux si tu dois aussi en supprimer le dossier :

Code :
  1. [[ $(ls /tmp/folder2 | grep -v "nfo$" | wc -l) -eq 0 ]] && rm -R /tmp/folder2
 

Bien sur a adapter si tu peux avoir des sous-dossier et autres.


Message édité par Nukolau le 11-07-2012 à 11:55:59
Reply

Marsh Posté le 11-07-2012 à 15:49:47    

Merci
mais  comment intégrer ca dans find ?. Je compte passer ca dans un crontab avec un repertoire racine et un find qui balaye le dossier et sous dossier du coup


---------------
=-Galerie Photo=- // Tekilaz :: Trop bon, Trop con... // FEEDB4CK
Reply

Marsh Posté le 16-07-2012 à 11:23:06    

up


---------------
=-Galerie Photo=- // Tekilaz :: Trop bon, Trop con... // FEEDB4CK
Reply

Marsh Posté le 17-07-2012 à 08:41:30    

Ça pourrait ressembler à ça (à tester/modifier):

 
Code :
  1. #!/bin/bash
  2. # on récupère la liste des répertoires en commençant par les plus profonds
  3. for i in `find /tmp/ -depth -type d`
  4. do
  5.     # on recherche les fichiers différents de *.nfo dans chaque rep, s'il y en a on passe
  6.     [[ -z $(find "$i" -maxdepth 1 -type f -not -name '*.nfo') ]] || continue
  7.     # sinon on supprime les *.nfo
  8.     find "$i" -maxdepth 1 -type f -name '*.nfo' -print0 | xargs -r0 rm
  9. done
  10. # on supprime les reps vides.
  11. find /tmp/ -depth -type d -empty -print0 | xargs -r0 rmdir


Message édité par tuxerman12 le 17-07-2012 à 08:42:38
Reply

Marsh Posté le 17-07-2012 à 14:36:44    

:love:  
ouep je vais essayer ça mais coté Algo ca me plait bien ! merci bien je vais adapter mais ca me parait nickel


---------------
=-Galerie Photo=- // Tekilaz :: Trop bon, Trop con... // FEEDB4CK
Reply

Marsh Posté le 19-07-2012 à 14:23:26    

find a une option -delete, plutot que de piper dans xargs :)


---------------
uptime is for lousy system administrators what Viagra is for impotent people - mes unixeries - github me
Reply

Marsh Posté le 19-07-2012 à 14:49:04    

-delete n'est pas une option a utiliser sans faire très gaffe dans find.
 
Déja parce qu'elle ne prend pas en compte toutes les options qui suivent (donc find -delete -iname 'tata' = find -delete, ca effacera tout), pas compatible avec l'option -prune.
 
Donc c'est le genre d'options qui peut matcher totalement autre chose que ce que tu pensais matcher avec ton find.

Reply

Marsh Posté le 19-07-2012 à 15:01:52    

c'est pour ça qu'on la met toujours en dernier :D et qu'en plus on efface rarement les fichiers par un find direct mais plutot après vérification via un -print


---------------
uptime is for lousy system administrators what Viagra is for impotent people - mes unixeries - github me
Reply

Marsh Posté le 19-07-2012 à 18:39:23    

find, c'est le genre de commande que j'aliase sur la plupart des systèmes
dont j'ai/ai eu la responsabilité plus ou moins directe :D
 
Pour donner une bonne image des effets possibles d'un find "bien senti",
je cite souvent l'expression "lâcher une merde dans le ventilo" [:ocolor]
 
Y'en a partout après ça et bonjour le "nettoyage" [:marc]


---------------
« Ce qui ne vous tue pas vous rend plus fort » F. Nietzsche | « Vise_ la Lune. Si tu rates, au pire, t'es dans la merde » Un poète disparu dans le cercle
Reply

Marsh Posté le 19-07-2012 à 18:39:23   

Reply

Marsh Posté le 19-07-2012 à 19:59:02    

Il y a aussi l'option -exec de find, qui peut être pratique dans bon nombre de circonstances.

 

Par exemple, pour la suppression de fichier on peut utiliser :

find /toto -type f -name 'titi.*' -exec rm -f {} \;

 

Si on est pas sûr on peut toujours passer par une suppression interactive (avec rm -i).
Mais ce n'est pas forcément une bonne idée dépendant du nombre de résultats retourné par find, à moins d'aimer appuyer répétitivement sur une touche  :D

Message cité 1 fois
Message édité par THRAK le 19-07-2012 à 20:02:03

---------------
THRAK (def.) : 1) A sudden and precise impact moving from intention, direction and commitment, in service of an aim. 2) 117 guitars almost striking the same chord simultaneously.
Reply

Marsh Posté le 19-07-2012 à 21:49:35    

on peut scripter l'appui sur la touche avec expect  [:idee]


---------------
Que va-t-il se passer cette gelgamar ? vous le découvrirez janamont à 20h
Reply

Marsh Posté le 20-07-2012 à 09:33:30    

THRAK a écrit :

Il y a aussi l'option -exec de find, qui peut être pratique dans bon nombre de circonstances.
 
Par exemple, pour la suppression de fichier on peut utiliser :

find /toto -type f -name 'titi.*' -exec rm -f {} \;


 
Si on est pas sûr on peut toujours passer par une suppression interactive (avec rm -i).
Mais ce n'est pas forcément une bonne idée dépendant du nombre de résultats retourné par find, à moins d'aimer appuyer répétitivement sur une touche  :D


 
rm est vite limité niveau nombre d'arguments, je crois que ton find injecte toute la liste en 1 fois tel que tu l'as écrit.

Reply

Marsh Posté le 20-07-2012 à 21:24:14    

Pour moi, le rm est effectué fichier par fichier.  
Simple test, tu remplaces le rm par un ls et tu verras bien que le exec est effectué à chaque qu'un fichier est trouvé.


---------------

Reply

Marsh Posté le 20-07-2012 à 23:41:23    

Oui.  :jap:

 

L'argument passé dans {} est le résultat courant ; la commande spécifiée est exécutée sur chaque résultat trouvé.


Message édité par THRAK le 20-07-2012 à 23:42:50

---------------
THRAK (def.) : 1) A sudden and precise impact moving from intention, direction and commitment, in service of an aim. 2) 117 guitars almost striking the same chord simultaneously.
Reply

Marsh Posté le 21-07-2012 à 10:32:52    

Pas forcément :
find ... -exec command {} \;
=> pour chaque fichier
find ... -exec command {} \+
=> une seule commande pour tous les fichiers qui matchent la recherche de find.


---------------
Ce n'est point ma façon de penser qui a fait mon malheur, c'est celle des autres.
Reply

Marsh Posté le 13-12-2012 à 17:10:13    

Bon étant un peu têtu je me suis recreusé un peu la tête et cela fonctionne :
J ai recontré des problèmes avec les espaces, du coup je suis passé par la modif de l IFS pour etre tranquille:
je vous met le code :
Mon dossier cible est /home/done
# on enleve l espace du IFS

Code :
  1. IFS=$'\n\t'
  2. # on cherche tous les nfo présents
  3. for fold in `find /home/done/ -type f -iname '*.nfo'`
  4.          do
  5. # on recupere le repertoire contenant le nfo
  6.                 base=$(dirname "$fold" )
  7. # on compte le nb de fichiers présents dans ce rep (si c est 1 on supprimer le rep car c est le nfo sinon bah on laisse)
  8.                 counter=`ls "$base" |wc -l`
  9.                 if [ $counter -eq 1 ]; then
  10.                         echo "deleting..." $fold
  11.                         rm -rf "$base"
  12.                 fi
  13.         done
  14. #et on oublie pas de remettre le IFS au propre!
  15. unset IFS


 
 
Voila en esperant que cela aide quelqu'un un jour!


---------------
=-Galerie Photo=- // Tekilaz :: Trop bon, Trop con... // FEEDB4CK
Reply

Marsh Posté le 13-12-2012 à 17:36:47    

Citation :

Voila en esperant que cela aide quelqu'un un jour!


Je vais pas te le faire à la J.P.Coffe, mais l'envie est bien là ! :fou:  
 
J'espère bien que personne ne reprendra ce code de débutant.
Et c'est valable pour tous ceux qui font une boucle for sur la sortie d'une commande. :kaola:  
 

Code :
  1. #!/bin/sh
  2. find ~ -type d | while read d
  3. do nf=0
  4.    for f in "$d"/*; do test -f "$f" && nf=$(($nf + 1)); done
  5.    test $nf -eq 1 && test "${f##*.}" = nfo && echo "rm -rf \"$d\""
  6. done

Reply

Marsh Posté le 14-12-2012 à 09:32:15    

non au contraire, merci !  
je regarde ça, c est un poil plus compliqué par contre mais j avoue c est carrément plus propre...
Pourquoi c est mal la boucle sur une sortie standard?


Message édité par tekilaz le 14-12-2012 à 09:40:17

---------------
=-Galerie Photo=- // Tekilaz :: Trop bon, Trop con... // FEEDB4CK
Reply

Marsh Posté le 14-12-2012 à 12:17:19    

Citation :

c est un poil plus compliqué

un poil pré-nubile XD
 

Citation :

Pourquoi c est mal la boucle sur une sortie standard?


Parce que la boucle va considérer chaque mot de la sortie et tourner dessus;
D'ailleurs, tu t'en es aperçu puisque tu as dû modifier l'IFS.
 
help read
[read] Lit une ligne depuis l'entrée standard [...]


Message édité par Profil supprimé le 14-12-2012 à 12:17:58
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed