Page 1 sur 3

Commande "touch" ... ou équivalent sur une arborescence

Posté : jeu. 13 juil. 2017 18:09
par tioker
Bonjour,

J'ai cherché sur le forum, j'ai lu les tutoriels, j'ai regardé l'aide (touch --help); j'ai pas trouvé.
Mon but: modifier la date d'un répertoire et de tous les fichiers et répertoires qui sont en dessous.
La commande "touch" ne semble modifier que les fichiers nommés ou les fichier du même niveau, pas ceux d'en dessous.

Exemple d'utilisation:
touch -t 201701011200 *
Dans l'attente ... Merci d'avance.

Re: Commande "touch" ... ou équivalent

Posté : ven. 14 juil. 2017 09:41
par tioker
Bonjour,
Entre le feu d'artifice et la fanfare du 14 juillet, j'ai cherché...
... sans succès pour l'instant, même si j'avance.
La commande touch -t met bien à jour les caractéristiques de fichiers ... dont la date.
La commande ls -R énumère les fichiers sous-répertoires compris, mais je n'y ai pas retrouvé la possibilité d'avoir l'adresse complète d'un fichier...
... chose que fait la commande readlink -f sans descendre dans les niveaux en dessous.
En plus, dans un boucle comme celle-ci:
#!/bin/bash
for fichier in `ls`
do
echo "Fichier trouvé : $fichier"
done
puisque j'ai des noms de fichiers comportant des espaces, le résultat est inutilisable.
Résultat:
Fichier trouvé : Various-Haute
Fichier trouvé : Musique
Fichier trouvé : CD1
pour un fichier répertoire qui s'appelle 'Various-Haute Musique CD1'.
Si le nom de fichier avait été en un seul mot j'aurais pu mettre ma commande touch dans la boucle mais là impossible.

La seule solution que je vois actuellement est de supprimer tous les espaces de mes noms de fichiers (les remplacer par "_" par exemple), de mettre tous les fichiers sur la même racine et d'appliquer ma commande touch. Mais comment remettre les fichiers à leur ancienne place, d'autant plus que les noms de répertoires ont eux aussi des espaces ...

A SUIVRE...

Re: Commande "touch" ... ou équivalent

Posté : ven. 14 juil. 2017 10:59
par arghlub
Salut tioker ;)

Tu devrais pas avoir besoin de passer par une boucle for...
Teste cette commande (j'ai repris la date que tu donnais dans l'option -t) :

Code : Tout sélectionner

find . -exec touch -t 201701011200 {} \;
Je viens de tester pour vérifier... chez moi ça marche (même avec les fichiers avec des espaces et bien sûr dans les sous-répertoires en “récursif”).

Petite explication de la commande :
  1. find . = on cherche n'importe quel fichier dans le répertoire courant et ses sous-répertoires
  2. -exec touch -t 201701011200 {} \; = on exécute la commande touch -t ... avec les noms des fichiers retournés par la commande find en arguments ({})
;)

Re: Commande "touch" ... ou équivalent

Posté : ven. 14 juil. 2017 11:50
par tioker
Bonjour,

Trop fort le arghlub!
En fait, même pas besoin de boucle for. Lancer simplement la commande au plus haut de l'arborescence qu'on veut modifier suffit.
De la puissance du scripting Linux ;)
Merci encore, je mets à résolu.
*
PS: j'ai modifié le titre pour qu'il soit plus générique, la solution pouvant s'appliquer à plein de cas et commandes différentes.

Re: Commande "touch" ... ou équivalent sur une arborescence

Posté : ven. 14 juil. 2017 15:42
par arghlub
;)
Ceci dit ...
tioker a écrit : De la puissance du scripting Linux ;)
... là c'est du “scripting” très simple et basique... perso quand je parle de script Shell, c'est plutôt de véritables petits programmes...

D'ailleurs, petit exercice (très simple en script bash) : tu pourrais faire un script assez simple avec la ligne de commande du dessus pour que cela soit plus convivial.
Par exemple, un script que tu nommerais changeDate.sh et que quand tu le lances (c'est plus simple de retenir changeDate que la commande entière) :
  • il te donne la liste des fichiers du répertoire (et de ses sous-répertoires)
  • et surtout qu'il te pose la question de quelle date tu veux leur mettre (avec vérification que le formatDate est bon)
  • petit plus subsidiaire : possibilité de mettre directement la date en paramètre au lancement de la commande, en lançant par exemple directement : «changeDate -201701011200»
À tes méninges... :ugeek:

Re: Commande "touch" ... ou équivalent sur une arborescence

Posté : ven. 14 juil. 2017 17:01
par tioker
Effectivement, mon script s'est changé en ligne de commande.

Je vais m'atteler à ton exercice, mais là c'est le tour de France :D .

Heureusement j'ai mon Chromebook sur les genoux pour répondre (excuses :shock: aux oreilles sensibles, Chromebook c'est pas du monde libre ... mais un Chromebook c'est tellement bien,tellement efficace, tellement portable et tellement autonome...).
Dès que j'ai fini ;) , je fait une livraison au Forum.

PS: pourquoi je fais ça ?
J'ai rippé plein de CD de musique Classique de ma collection (soit par abcde, soit en switchant par iTunes sur mon Win10 (1). Mais les outils de rippages utilisent les bases de données du Web ... qui donnent comme artiste les interprètes et non pas les compositeurs. Donc si je cherche dans mon lecteur (Clementine) les dernières entrées, je vois pleins d'interprètes (orchestre, chanteurs d'opéra...) et non pas le compositeur. Donc comme je sais que j'ai ces compositeurs en mp3, je peux les chercher par le répertoire plutôt que par la base de données du lecteur. Utile quand on a la discographie complète des œuvres de Mozart, Bach, Beethoven, ou Verdi... Ainsi les mettre dans une date du passé permet de les exclure des derniers disques enregistrés.

(1) pourquoi iTunes? Rippage direct oui mais surtout ... avec le même ordinateur (double boot), le rippe avec abcde en 2x et en 20x (voir plus) avec iTunes. Bon c'est hors sujet mais c'est pour causer...

A SUIVRE...

Re: Commande "touch" ... ou équivalent sur une arborescence

Posté : sam. 15 juil. 2017 23:52
par tioker
arghlub a écrit : ;)
D'ailleurs, petit exercice (très simple en script bash) : tu pourrais faire un script assez simple avec la ligne de commande du dessus pour que cela soit plus convivial.
Par exemple, un script que tu nommerais changeDate.sh et que quand tu le lances (c'est plus simple de retenir changeDate que la commande entière) :
  • il te donne la liste des fichiers du répertoire (et de ses sous-répertoires)
  • et surtout qu'il te pose la question de quelle date tu veux leur mettre (avec vérification que le formatDate est bon)
  • petit plus subsidiaire : possibilité de mettre directement la date en paramètre au lancement de la commande, en lançant par exemple directement : «changeDate -201701011200»
À tes méninges... :ugeek:
J'ai suivi tes conseils, et j'ai écrit la procédure.
Elle accepte deux paramètres: P1=répertoire (et arborescence) à modifier, P2=date sous forme YYYYMMDDHHMM.
La procédure vérifie:
- qu'on a bien mis 2 paramètres
- que le répertoire est valide
- que la date est bonne, aussi bien en année qu'en mois, jour heure et minutes
- et demande confirmation qu'on veut bien faire le changement
Bon j'ai pioché sur le net pour des tests pas évidents pour moi, mais ça marche ... comme je le veux.
Je ne sais pas associer à ce message la procédure elle-même, sauf à la mettre en texte... plus de 100 lignes. Une idée ?
J'ai appris qu'il y avait plein de subtilités dans le shell, il va falloir que je m'attaque à de la literature sérieuse sur le sujet.
Voilà. Saine occupation du soir, le jour étant réservé au dehors.

A la prochaine

Re: Commande "touch" ... ou équivalent sur une arborescence

Posté : dim. 16 juil. 2017 05:43
par arghlub
Aaahh, je suis curieux de jeter un œil à ton code.
+ de 100 lignes de code (il y a peut-être moyen de l'optimiser)... ben dis donc je vois que t'as bien fait tes devoirs! :D

Pour le partager facilement, tu peux utiliser un service de “pastebin”. Il y en a plein sur le web, par exemple : Au plaisir de lire ta prose codistique ;)

Re: Commande "touch" ... ou équivalent sur une arborescence

Posté : dim. 16 juil. 2017 10:38
par tioker
Bonjour,

Bon je me lance. Merci d'avance pour ta participation, ta patience... et ta clémence sur cette livraison.
Lien est là --> https://zerobin.net/?1e695d79bc9a3125#S ... /2K7ASdmc=.
Je pense que j'ai fait les bonnes manipulations pour le mettre en partage; il est d'ailleurs ouvert à tous, on peut s'en inspirer.

J'avoue tout de même mes difficultés:
- dans l'évaluation des variables, j'ai toujours un peu de mal. Par exemple entre la variable folder, $folder, [$folder] voir (( $folder)) mon esprit s'enbrouille.
- pour les boucles if, même si ça parait simple, j'aurai aimé tout pourvoir mettre sur une même ligne. C'est plus compacte et pour moi mieux à lire. On n'est pas là pour faire du volume...
- Il y a sûrement des endroits où on peut optimiser, en particulier si j'avais utilisé des des or ou des and dans les tests.
-Aussi sur la date; peut-être en utilisant un masque ou en comparant avec un format (genre Excel) on pourrait rapidement voir si la date est bonne, en une seule ligne (ou presque)
- si les paramètres P1 et P2 sont inexistants, on peut les demander; mais là c'est pas sorcier

Voilà. Si toi (arghlub) ou d'autres veulent me donner des conseils, je suis preneur.
Et si vous avez la référence d'un ouvrage ou d'un site assez complet de vulgarisation sur Linux, je suis preneur. Celui que j'ai (livre) est assez ancien (20 ans) et tous les sites ne se valent pas.

Au plaisir de vous lire et profitez tout de même de cette belle journée :D !

Re: Commande "touch" ... ou équivalent sur une arborescence

Posté : dim. 16 juil. 2017 12:31
par arghlub
Super, ton partage est nickel... 8-)
J'ai donc enregistré ton script et y jetterai un coup d'œil dès que j'aurais un peu de temps (dimanche=famille).

Après un coup d'œil en diagonale sur ton script : je vois que t'as commenté tout ça : c'est super ! (pour toi dans le futur, et pour ceux qui vont scruter ton code)
Bref, je ne tarderai pas à te faire mes retours.
;)

ps : par rapport aux conditions if sur une ligne, tu peux le faire en ponctuant chaque instruction avec un point-virgule. En reprenant la première condition de ton script :

Code : Tout sélectionner

if test -z "$1"; then echo "$lib0 (P1) $libempty"; exit; fi