#1 Le 17/07/2019, à 20:04
- sojoachim
[Résolu] Identifier si il s'agit d'un fichier ou d'un dossier
Bonjour à tous,
Actuellement je me fais un petit script pour le "fun" & apprendre un peu.
Une partie de ce script devra couper les fichiers d'un dossier.
Le problème que je rencontre est que ce dossier contient un dossier et que mv agit dessus.
Or mon but est de couper QUE les fichiers & d'ignorer les dossiers.
Dit autrement :
Le dossier "test" contient 3 fichiers et un fichier nommer "archive"
Action du script : couper les 3 fichiers & les placer dans le dossier "archive"; et ignorer le dossier "archive"
Mon script :
mv /home/user/Bureau/test/* ./archive/
Les fichiers sont déplacés mais j'ai le message d'erreur suivant :
mv: impossible de déplacer '/home/user/Bureau/test/archive' vers un sous-répertoire de lui-même, './archive/archive'
Je peux contourner le problème en cachant le dossier archive cependant ....
Dans le but de 'savoir faire' j'aimerai que la commande mv ne s'applique uniquement pour les fichiers.
Avez vous une idée suggestion ???
Après quelques recherches j'ai essayé la commande
test
L'idée est d'utilisé l'argument -s qui correspond à 'il s'agit d'un fichier' & qui doit retourner la valeur true (si j'ai bien compris)
Cependant, je pense que je l'utilise mal & la lecture du man ne m'aide pas... Il doit me manquer des connaissances en bash.
Merci par avance pour vos retours
Joachim
Dernière modification par sojoachim (Le 19/07/2019, à 19:25)
Hors ligne
#2 Le 17/07/2019, à 20:23
- pingouinux
Re : [Résolu] Identifier si il s'agit d'un fichier ou d'un dossier
Bonsoir,
for fic in /home/user/Bureau/test/*
do
test -f "$fic" && echo mv -i "$fic" /home/user/Bureau/test/archive
done
À tester. Si c'est bon, tu enlèves le echo.
Le paramètre -i te prévient si un fichier de même nom existe déjà.
Ajouté :
test -s f
renvoie true si f est un fichier non vide ou un répertoire, vide ou non.
Dernière modification par pingouinux (Le 17/07/2019, à 20:31)
Hors ligne
#3 Le 18/07/2019, à 06:40
- DonutMan75
Re : [Résolu] Identifier si il s'agit d'un fichier ou d'un dossier
Hello,
une autre solution avec find ?
$ find /home/user/Bureau/test/ -type f -maxdepth 0 -exec mv -i {} /home/user/Bureau/test/archive \;
Donut
Hors ligne
#4 Le 18/07/2019, à 07:11
- pingouinux
Re : [Résolu] Identifier si il s'agit d'un fichier ou d'un dossier
@DonutMan75 #3 :
find a l'avantage de voir aussi les fichiers cachés, mais il faut utiliser ces paramètres
find ... -mindepth 1 -maxdepth 1 ...
Hors ligne
#5 Le 18/07/2019, à 07:19
- MicP
Re : [Résolu] Identifier si il s'agit d'un fichier ou d'un dossier
Bonjour
find /home/user/Bureau/test/ -maxdepth 1 -type f -execdir mv -i {} /home/user/Bureau/test/archive/ \;
Hors ligne
#6 Le 18/07/2019, à 08:50
- sojoachim
Re : [Résolu] Identifier si il s'agit d'un fichier ou d'un dossier
Bonjour
Merci pour vous retours/pistes si rapides!
Je regarde ça des que ma fille me laisse le temps de mettre la main sur mon pc
Hors ligne
#7 Le 18/07/2019, à 09:13
- kamaris
Re : [Résolu] Identifier si il s'agit d'un fichier ou d'un dossier
Il vaudrait mieux protéger les noms de fichiers au cas où il y aurait des espaces ou caractères spéciaux dedans aussi :
find /home/user/Bureau/test/ -maxdepth 1 -type f -execdir mv -i '{}' /home/user/Bureau/test/archive/ \;
Hors ligne
#8 Le 18/07/2019, à 13:15
- MicP
Re : [Résolu] Identifier si il s'agit d'un fichier ou d'un dossier
J'avais testé avec succès la ligne de commandes
avec des fichiers dont les noms contiennent
des caractères espace et autres caractères spéciaux.
michel@debg53sw:~$ ls -lR Bureau/test/
Bureau/test/:
total 20
drwxr-xr-x 2 michel michel 4096 juil. 18 14:12 archive
-rw-r--r-- 1 michel michel 45 juil. 18 07:54 fich_2.txt
-rw-r--r-- 1 michel michel 45 juil. 18 07:54 fich_3 avec espace.txt
-rw-r--r-- 1 michel michel 36 juil. 18 07:54 fich_4 avec espace.txt
-rw-r--r-- 1 michel michel 0 juil. 18 14:17 fich à µ @jh .txt
-rw-r--r-- 1 michel michel 9 juil. 18 08:01 jhgkjhghjg.txt
Bureau/test/archive:
total 0
michel@debg53sw:~$
michel@debg53sw:~$ find /home/michel/Bureau/test/ -maxdepth 1 -type f -execdir mv -i {} /home/michel/Bureau/test/archive/ \;
michel@debg53sw:~$
michel@debg53sw:~$ ls -lR Bureau/test/
Bureau/test/:
total 4
drwxr-xr-x 2 michel michel 4096 juil. 18 14:13 archive
Bureau/test/archive:
total 16
-rw-r--r-- 1 michel michel 45 juil. 18 07:54 fich_2.txt
-rw-r--r-- 1 michel michel 45 juil. 18 07:54 fich_3 avec espace.txt
-rw-r--r-- 1 michel michel 36 juil. 18 07:54 fich_4 avec espace.txt
-rw-r--r-- 1 michel michel 0 juil. 18 14:17 fich à µ @jh .txt
-rw-r--r-- 1 michel michel 9 juil. 18 08:01 jhgkjhghjg.txt
michel@debg53sw:~$
Dernière modification par MicP (Le 18/07/2019, à 13:23)
Hors ligne
#9 Le 18/07/2019, à 15:02
- kamaris
Re : [Résolu] Identifier si il s'agit d'un fichier ou d'un dossier
Non, je dis effectivement une bêtise : ce sont les accolades elles-mêmes qui devraient être protégées de l'interprétation par le shell (comme on protège le point-virgule), mais ça à l'air plutôt daté : https://unix.stackexchange.com/question … ells-which
J'ai toujours cru qu'il s'agissait de protéger le contenu des accolades, désolé.
EDIT : mis à part quand même le cas cité avec un sous-shell dans le lien ci-dessus :
find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d {}' \;
ls: cannot access /home/stefan/Ubuntu: No such file or directory
ls: cannot access One: No such file or directory
au lieu de
find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d "{}"' \;
/home/stefan/Ubuntu One
Comme quoi les protections en shell, ça reste toujours un peu casse-gueule…
Dernière modification par kamaris (Le 18/07/2019, à 15:23)
Hors ligne
#10 Le 18/07/2019, à 20:44
- sojoachim
Re : [Résolu] Identifier si il s'agit d'un fichier ou d'un dossier
TOP !
Merci pour vos retours : cela m'a permis de faire des liens avec des notions que j'avais lu mais pas "intégré"
Du coup j'ai pu finaliser mon script en allégeant le nombre de ligne :-)
En faite mon objectif final est de faire une copie de mes mots de passe sur mon serveur local afin d'y accéder sur mes 3 machine, avec un dossier d'archive. Afin d'archiver mes fichiers, je colle un suffixe au fichier (la date du jour). Ainsi, j'ai tout l'historique des modifications si j'ai fais une boulette un jour.
Voici le code final :
#!/bin/bash
find /home/pytolux/Bureau/test/ -maxdepth 1 -type f -execdir
mv -i '{}' /home/pytolux/Bureau/test/archive/'{}'_`date +%Y%m%d` \;
J'aurai préférer le mettre en préfixe car mes fichiers comportent systématiquement des extensions.
J'ai essayé la syntaxe suivante :
`date +%Y%m%d`_'{}' \;
Mais... cela ne fonctionne pas. Les accolades doivent au chemin du fichier & non à son nom.
Je pourrai faire cette opération avec une 3ème ligne de code mais... je suis curieux de savoir si je peux le faire sans rajouter une 3ème opération.
Il va falloir que je recherche comment faire -> je pense partir sur les expressions régulière avec l'option -regex de find... mais il faut que je creuse...
@pingouinux
Pour la commande test : J'avais compris qu'elle retourner la valeur true ou false mais je ne savais pas comment l'utiliser.
Donc si j'ai bien compris :
on fait le test avec la commande test pour savoir si il s'agit d'un fichier ou non : si true alors la commande est réussite et le && va permettre de lancer la commande suivante.
Le cas contraire, si on a false, la commande est un échec et le && ne permettra pas le lancement de la commande.
C'est ça ?
@aux autres
Concernant find :
Je n'avais pas vu dans le man l'argument -exec et -execdir.
Effectivement .... ça aide pour lancer une commande
maxdepth ou mindepth doivent être placé avant l'argument -type c'est ça ?
Merci encore à vous tous pour votre aide
Hors ligne
#11 Le 19/07/2019, à 03:20
- MicP
Re : [Résolu] Identifier si il s'agit d'un fichier ou d'un dossier
Bonjour
…J'aurai préférer le mettre en préfixe …
find /home/pytolux/Bureau/test/ -maxdepth 1 -type f -execdir /bin/bash -c 'f="{}"; mv -i "$f" "./archive/$(date +%Y%m%d)_${f#*/}"' \;
pytolux@nommachine:~$ mkdir -p /home/pytolux/test/archive # Pour créer les répertoires de test
pytolux@nommachine:~$
pytolux@nommachine:~$ touch "/home/pytolux/Bureau/test/fich_3 avec espace.txt" "/home/pytolux/Bureau/test/jhg @ ça et là avec espace.txt" "/home/pytolux/Bureau/test/fich_4 avec espace.txt"
pytolux@nommachine:~$
pytolux@nommachine:~$ ls -l /home/pytolux/Bureau/test/*.*
-rw-r--r-- 1 pytolux pytolux 0 juil. 19 04:12 /home/pytolux/Bureau/test/fich_3 avec espace.txt
-rw-r--r-- 1 pytolux pytolux 0 juil. 19 04:12 /home/pytolux/Bureau/test/fich_4 avec espace.txt
-rw-r--r-- 1 pytolux pytolux 0 juil. 19 04:12 /home/pytolux/Bureau/test/jhg @ ça et là avec espace.txt
pytolux@nommachine:~$
pytolux@nommachine:~$ ls -l /home/pytolux/Bureau/test/archive/*.*
ls: impossible d'accéder à '/home/pytolux/Bureau/test/archive/*.*': Aucun fichier ou dossier de ce type
pytolux@nommachine:~$
pytolux@nommachine:~$ find /home/pytolux/Bureau/test/ -maxdepth 1 -type f -execdir /bin/bash -c 'f="{}"; mv -i "$f" "./archive/$(date +%Y%m%d)_${f#*/}"' \;
pytolux@nommachine:~$
pytolux@nommachine:~$ ls -l /home/pytolux/Bureau/test/*.*
ls: impossible d'accéder à '/home/pytolux/Bureau/test/*.*': Aucun fichier ou dossier de ce type
pytolux@nommachine:~$
pytolux@nommachine:~$ ls -l /home/pytolux/Bureau/test/archive/*.*
-rw-r--r-- 1 pytolux pytolux 0 juil. 19 04:12 /home/pytolux/Bureau/test/archive/20190719_fich_3 avec espace.txt
-rw-r--r-- 1 pytolux pytolux 0 juil. 19 04:12 /home/pytolux/Bureau/test/archive/20190719_fich_4 avec espace.txt
-rw-r--r-- 1 pytolux pytolux 0 juil. 19 04:12 /home/pytolux/Bureau/test/archive/20190719_jhg @ ça et là avec espace.txt
pytolux@nommachine:~$
pytolux@nommachine:~$ rm -rf /home/pytolux/Bureau/test # Pour effacer les répertoires et fichiers de test
=======
…
maxdepth ou mindepth doivent être placé avant l'argument -type c'est ça ?
…
Oui,
comme le signale d'ailleurs
le message d'avertissement qui s'affiche quand on fait cette erreur
et que tu pourras lire ci-dessous :
michel@debg53sw:~$ find /home/michel/Bureau/test/ -type f -maxdepth 1
find: attention : vous avez spécifié l'option -maxdepth après un argument qui n'est pas une option -type mais les options sont positionnelles (-maxdepth affecte les tests spécifiés avant aussi bien qu'après). SVP spécifiez les options avant les autres arguments.
/home/michel/Bureau/test/nom fichier N° 4.txt
/home/michel/Bureau/test/nom fichier N° 3.txt
/home/michel/Bureau/test/nom fichier N° 5.txt
/home/michel/Bureau/test/nom fichier N° 1.txt
/home/michel/Bureau/test/nom fichier N° 2.txt
michel@debg53sw:~$
Dernière modification par MicP (Le 19/07/2019, à 07:47)
Hors ligne
#12 Le 19/07/2019, à 05:58
- pingouinux
Re : [Résolu] Identifier si il s'agit d'un fichier ou d'un dossier
@pingouinux
Pour la commande test : J'avais compris qu'elle retourner la valeur true ou false mais je ne savais pas comment l'utiliser.
Donc si j'ai bien compris :
on fait le test avec la commande test pour savoir si il s'agit d'un fichier ou non : si true alors la commande est réussite et le && va permettre de lancer la commande suivante.
Le cas contraire, si on a false, la commande est un échec et le && ne permettra pas le lancement de la commande.C'est ça ?
Oui
Hors ligne