#1 Le 06/02/2022, à 08:15
- Compte supprimé
[résolu] recherche/copie de fichier...
Bonjour,
Suite à une demande posée sur un forum python à propos d'une demande concernant une recherche/copie spécifique, je me suis dit ça c'est un truc à réaliser en bash
Voici l'énoncé:
Soit les fichiers suivants issus de répertoires différents:
Le_chien_miaule.wav, Le_Chat_aboie.wav, mon_toutou_le_CHIEN.wav, monchatalors.wav
Par ailleurs, nous avons les répertoires ~/Chien et ~/Chat
Le but de rechercher est de copier tous les fichiers comprenant dans le nom chien dans le répertoire ~/Chien et ceux comprenant chat dans ~/Chat.
J'ai pensé un truc du genre:
find / -iname '*chat*' -exec cp {} '/home/fab/Chat' \; 2> /dev/null
seulement comme en vrai il n'y a pas que chat chien à traiter mais des dizaines de mots clés pour des dizaines de répertoires, comment automatiser cette recherche à partir d'un tableau?
nom=(chien chat loup poupoule machin truc chose)
Dernière modification par Compte supprimé (Le 06/02/2022, à 22:48)
#2 Le 06/02/2022, à 09:17
- MicP
Re : [résolu] recherche/copie de fichier...
Bonjour
Oui, on pourrait utiliser la commande find dans une boucle for
qui lirait une liste de "motif de recherche + nom de répertoire cible" dans un tableau associatif
mais Il va y avoir deux autres problèmes à prendre en compte :
- La commande find va finir par trouver dans le répertoire /home/fab/Chat
des fichiers dont les noms contiennent le mot chat et elle va vouloir les copier dans ce même répertoire.
Donc, il faudra exclure de la recherche le répertoire cible de la copie.
- Il se peut aussi que le même nom de fichier soit trouvé dans des répertoires différents
et la copie du deuxième fichier écrasera le fichier qui a déjà été copié
Il va falloir décider quoi faire dans ce cas.
En utilisant l'option backup de la commande cp
on peut faire renommer la copie des doublons en les numérotant,
mais est-ce que ça conviendra au but recherché ?
=======
D'autre part, on n'a peut-être même pas besoin de la commande find pour faire la recherche,
et il y a des personnes beaucoup plus compétentes que moi qui viendront sans doute proposer une solution efficace.
Dernière modification par MicP (Le 06/02/2022, à 10:13)
Hors ligne
#3 Le 06/02/2022, à 09:59
- Compte supprimé
Re : [résolu] recherche/copie de fichier...
merci pour ta réponse, je vais essayer un code en partant de tes suggestions
- La commande find va finir par trouver dans le répertoire /home/fab/Chat
des fichiers dont les noms contiennent le mot chat et elle va vouloir les copier dans ce même répertoire.
Donc, il faudra exclure de la recherche le répertoire cible de la copie.
Il semble que le paramètre -prune fera l'affaire.
- Il se peut aussi que le même nom de fichier soit trouvé dans des répertoires différents
et la copie du deuxième fichier écrasera le fichier qui a déjà été copié
Il va falloir décider quoi faire dans ce cas.
Je vais considérer que si le nom du fichier est identique, c'est le même fichier. Donc j'écrase
Dernière modification par Compte supprimé (Le 06/02/2022, à 10:00)
#4 Le 06/02/2022, à 10:15
- MicP
Re : [résolu] recherche/copie de fichier...
… Je vais considérer que si le nom du fichier est identique, c'est le même fichier. Donc j'écrase …
Oui, étant donné qu'il ne s'agit pas d'un déplacement de fichiers,
les fichiers originaux seront toujours accessibles, si besoin.
=======
Peut-être même que, suivant le but recherché, plutôt que de faire des copies
la création de liens symboliques ferait économiser de l'espace disque
avec en plus l'avantage de ne pas avoir besoin de mettre à jour la copie si l'original est modifié.
Dernière modification par MicP (Le 06/02/2022, à 10:26)
Hors ligne
#5 Le 06/02/2022, à 13:54
- Watael
Re : [résolu] recherche/copie de fichier...
salut,
si j'ai bien compris, les mots-clés sont des répertoires, dans lesquels il faut copier les fichiers qui contiennent un de ces mots-clés.
#!/bin/bash
cheminDirs=/jeSais/pas/ou
cheminFichiers=/jeSais/pas/nonPlus
shopt -s nullglob extglob globstar
for dir in "$cheminDirs"/*/
do
motClef=${dir##*/}
motClef=${motClef%/*}
cp -t "$dir" "$cheminFichiers/**/*$motClef* ##le double astérisque n'est utile que si les fichiers peuvent être dans des sous-répertoires.
done
/!\ pas testé.
Dernière modification par Watael (Le 06/02/2022, à 15:58)
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#6 Le 06/02/2022, à 15:50
- Tawal
Re : [résolu] recherche/copie de fichier...
Hello,
Un petit s en trop non ?
motClef=${motClefs%/*}
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#7 Le 06/02/2022, à 15:55
- Watael
Re : [résolu] recherche/copie de fichier...
corrigé. merci.
j'ai corrigé "$cheminDirs"/motsClef/, qui ne sera pas trouvé.
for dir in "$cheminDirs"/*/
Dernière modification par Watael (Le 06/02/2022, à 16:00)
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#8 Le 06/02/2022, à 18:48
- Tawal
Re : [résolu] recherche/copie de fichier...
Avec plusieurs mots clefs (mis dans un tableau) :
#!/bin/bash
cheminDirs=/jeSais/pas/ou
cheminFichiers=/jeSais/pas/nonPlus
MotsClefs=( "Chien" "Chat" "Poisson" )
shopt -s nullglob extglob globstar
for dir in "${MotsClefs[@]/#/$cheminDirs\/}"
do
motClef=${dir##*/}
motClef=${motClef%/*}
cp -t "$dir" "$cheminFichiers/**/*$motClef*
done
Dernière modification par Tawal (Le 06/02/2022, à 18:53)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#9 Le 06/02/2022, à 18:59
- Watael
Re : [résolu] recherche/copie de fichier...
for dir in "${MotsClefs[@]/#/$cheminDirs\/}"
+1
bel usage du Remplacement de paramètres !
j'aurais fait un Développement entre accolades dans la définition du tableau : MotsClefs=( "$cheminDirs"/{Ch{ien,at},Poisson} )
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#10 Le 06/02/2022, à 19:02
- Tawal
Re : [résolu] recherche/copie de fichier...
Merci, ça fait plaisir
Edit:
Bien vu pour préparer correctement le tableau à l'avance
Dernière modification par Tawal (Le 06/02/2022, à 19:03)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#11 Le 06/02/2022, à 19:08
- Watael
Re : [résolu] recherche/copie de fichier...
seulement si le tableau est statique, et écrit dans le script.
sinon la méthode que tu as choisie est plus adaptée.
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#12 Le 06/02/2022, à 19:16
- Tawal
Re : [résolu] recherche/copie de fichier...
Oui, cela permet de dynamiser le tableau de différentes façons, passage de paramètres au script, fichier de configuration etc.
Tu montres aussi un bel exemple de développement par accolades, le h extérieur et commun à Chien et Chat permet de ne l'écrire qu'une fois, c'est concis !
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#13 Le 06/02/2022, à 20:05
- Compte supprimé
Re : [résolu] recherche/copie de fichier...
Bonjour,
si j'ai bien compris, les mots-clés sont des répertoires, dans lesquels il faut copier les fichiers qui contiennent un de ces mots-clés.
Pas vraiment les mots clefs sont des chaines de caractère... et il faut copier les fichiers dont le nom contient au minima cette chaine. Exemple: mot clef=chien. Sont éligibles les fichiers:
/truc/machin/il_est_beau_le_chien
/machin/chose/MonChien
/bidule/truc/Chienne_de_vie
J'ai suivi les suggestions de MicP (y compris la création de lien au lieu des copies des fichiers):
#!/bin/bash
declare -A nom=( [bidon]=/home/fab/BIDON/ [chien]=/home/fab/CHIEN/ )
for n in "${!nom[@]}"
do
find /home/fab/ -iname \*$n\* -exec cp -s {} ${nom[$n]} \;
done
Le code semble se comporter comme prévu
Dernière modification par Compte supprimé (Le 06/02/2022, à 22:47)
#14 Le 06/02/2022, à 20:12
- Compte supprimé
Re : [résolu] recherche/copie de fichier...
@Tawal: Désolé je n'avais pas vu ta proposition...
j'étais affairé à autre chose et je n'avais pas rafraîchi la page avant de répondre. Je vais regarder de plus près ta réponse (un peu plus tard)
merci
#15 Le 06/02/2022, à 20:33
- Tawal
Re : [résolu] recherche/copie de fichier...
Ta solution est plus "large", elle est insensible à la casse du nom de fichier.
Plus difficile à dynamiser le tableau de mots clefs mais possible.
Edit:
Mets des guillemets autour de ${nom[$n]} dans ton find et je protégerais le {} :
find /home/fab/ -iname \*$n\* -prune -exec cp -s '{}' "${nom[$n]}" \;
Les guillemets au cas où il y ait un espace dans le nom de fichier
Dernière modification par Tawal (Le 06/02/2022, à 20:39)
Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !
Hors ligne
#16 Le 06/02/2022, à 22:46
- Compte supprimé
Re : [résolu] recherche/copie de fichier...
Mets des guillemets autour de ${nom[$n]} dans ton find et je protégerais le {} :
find /home/fab/ -iname \*$n\* -prune -exec cp -s '{}' "${nom[$n]}" \;
Les guillemets au cas où il y ait un espace dans le nom de fichier
Dans ce cas ils ne sont pas vraiment utiles vu ${nom[$n]} correspond aux dossiers cibles dont je sais qu'ils ne contiennent pas d'espace
Par contre l'utilisation de -prune n'était pas pertinent, j'édite le code en conséquence.
Sinon c'est quand même puissant les options de short. Je viens de m'y référer pour comprendre vos codes (je connais ça de loin mais comme je ne pratique pas, j'oublie)
#17 Le 07/02/2022, à 00:11
- MicP
Re : [résolu] recherche/copie de fichier...
Tawal a écrit :… Les guillemets au cas où il y ait un espace dans le nom de fichier
Dans ce cas ils ne sont pas vraiment utiles …
[Humour (basé sur du vécu)]
Tu sais, si le monsieur il te dit de mettre des guillemets,
c'est que peut-être, comme moi un jour,
tout content de retrouver son script qui avait si bien marché l'autre fois,
et qui allait lui permettre de rendre son travail à l'heure (pour une fois),
il a dû galérer pendant des heures en se disant que "pourtant, ça marchait bien avant,
mais pourquôâââh … pourquôâââh ça ne marche pas !
le monde est cruel, c'est trop injuste, pourquoi c'est toujours à moi que ça arrive,
et c'est toujours quand on en a le plus besoin que ça marche pas… etc."
avant de se rendre compte, quelques jours plus tard,
après avoir reçu le nouveau clavier pour remplacer l'ancien qui avait explosé,
qu'il aurait quand même dû les mettre ces pu...ns de guillemets,
même s'ils ne servaient à rien sur le moment.
[/humour]
Dernière modification par MicP (Le 07/02/2022, à 00:35)
Hors ligne
#18 Le 07/02/2022, à 07:58
- Compte supprimé
Re : [résolu] recherche/copie de fichier...
Par association d'idées ta vidéo me fait penser à la chanson Monsieur l'Agent de Boby Lapointe:
Je m’énerve,
Je m’énerve,
Je m’éner ner ner ner ner ner ner ve.
Pour ce qui est du script, mon intérêt n'était que purement ludique, je l'avais écrit en python et je me suis dit que c'était plutôt un truc à écrire en bash où tout est fichier.
Pour le coup, effectivement bash est préférable: plus rapide et plus court. Par contre, difficilement lisible. Je plains les personnes qui doivent maintenir du code écrit en bash^^ mais peut être que j'ai ce sentiment parce que je ne le pratique pas
#19 Le 07/02/2022, à 08:48
- Watael
Re : [résolu] recherche/copie de fichier...
"tout est fichier" sur UNIX/Linux. Tout ce qui vient par-dessus, hérite de cette conception.
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#20 Le 07/02/2022, à 14:16
- Compte supprimé
Re : [résolu] recherche/copie de fichier...
Pour en revenir à la question des espaces dans les fichiers, je note que sur mon pc, les fichiers qui en comportent sont des fichiers venant du net (n'en mettant pas personnellement):
Du coup depuis mon dossier personnel un petit:
shopt -s globstar
rename -n 's/ /_/g' **/*.mkv **/*.mp4 **/*.wav **/*.avi
et tous les espaces deviennent des _
note: enlever le -n pour un renommage effectif
Dernière modification par Compte supprimé (Le 07/02/2022, à 14:18)
#21 Le 07/02/2022, à 15:00
- Watael
Re : [résolu] recherche/copie de fichier...
ne cherche pas d'échappatoires.
« il faut toujours* mettre des guillemets autour des Développements de variables. TOUJOURS ! »
--
* à moins de savoir pourquoi.
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#22 Le 07/02/2022, à 17:41
- Compte supprimé
Re : [résolu] recherche/copie de fichier...
Je ne le ferais plus.
Croix de bois, croix de fer, si je mens, je vais en enfer !
#23 Le 07/02/2022, à 20:33
- MicP
Re : [résolu] recherche/copie de fichier...
…si je mens, je vais en enfer !…
Justement, le titre du film dont j'ai donné un lien vers ce court extrait est : Ma vie est un Enfer (réalisé par Josiane Balasko)
Dernière modification par MicP (Le 07/02/2022, à 20:53)
Hors ligne