Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 17/07/2019, à 21: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, à 20:25)

Hors ligne

#2 Le 17/07/2019, à 21: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, à 21:31)

Hors ligne

#3 Le 18/07/2019, à 07: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, à 08: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, à 08: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, à 09: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, à 10: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, à 14: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, à 14:23)

Hors ligne

#9 Le 18/07/2019, à 16: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, à 16:23)

Hors ligne

#10 Le 18/07/2019, à 21: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  big_smile

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, à 04:20

MicP

Re : [Résolu] Identifier si il s'agit d'un fichier ou d'un dossier

Bonjour

Dans son message #10, sojoachim a écrit :

…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

=======

Dans son message #10, sojoachim a écrit :


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, à 08:47)

Hors ligne

#12 Le 19/07/2019, à 06:58

pingouinux

Re : [Résolu] Identifier si il s'agit d'un fichier ou d'un dossier

sojoachim a écrit :

@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