Je veux écrire un programme Shell qui va parcourir tous les dossiers dont les noms correspondent à un modèle comme celui-ci:
Sudo sh Shell.sh pub
Lorsqu'il est exécuté, le script recherche tous les dossiers dont le nom contient pub
et affiche sa date de modification. Je souhaite avoir un code qui imprimera les résultats comme dans cette image: J'ai ce code mais il ne me donne pas le résultat que j'attends.
echo 'the folder '$1' was modified at ';
find -type d -name 'kam*' -exec stat -c '%y %n' '{}' \;
Je dois parcourir tous les dossiers et sortir le texte echo 'the file '$1' was modified at ';
et imprimer la date comme dans l'image.
Je voudrais un résultat comme celui-ci:
netcom@hotspot:~$ bash script.sh testRegex Pub
the folder testRegex was modified on may 15 01:19
the folder Public was modified on may 19 01:19
the folder Pubos was modified on may 19 01:19
Vous pouvez utiliser find
lui-même pour imprimer le tout:
for pattern
do
find . -type d -name "*$pattern*" -printf 'The folder %P was modified on %t\n'
done
for pattern; do ... done
parcourt tous les arguments, la variable pattern
étant définie sur chaque argument.
Avec find
, %P
et %t
donnent le chemin d'accès au fichier et l'heure de modification dans -printf
.
Vous pouvez utiliser bash
avec l'option globstar
activée comme dans le script suivant:
#!/bin/bash
shopt -s globstar
for i
do for k in **/"$i"*/
do stat -c "the folder %n was modified on %y" "$k"
done
done
Enregistrez-le sous script
, rendez-le exécutable avec chmod +x script
et appelez-le comme vous le souhaitiez:
bash /path/to/script testRegex Pub
Notez que ceci recherchera par exemple Pub*
, si vous voulez réellement faire correspondre *Pub*
, remplacez **/"$i"*/
par **/*"$i"*/
. Si vous souhaitez raccourcir l'horodatage, essayez d'ajouter | sed 's/:[^:]*$//'
à la fin de la ligne do stat
. Vous devriez également essayer %N
au lieu de %n
, en particulier pour les noms de répertoire avec des espaces, ce format est préférable.
Si vous souhaitez un contrôle plus précis du format de date, vous pouvez utiliser date
, en remplaçant la ligne do stat
par ce qui suit:
do date -d@$(stat -c%Y "$k") +"the folder $k was modified on %b %d %R"
Vous pouvez ensuite utiliser les séquences de format date
habituelles expliquées dans man date
, celle-ci est imprimée ici par exemple. May 15 01:19
comme vous l'avez demandé.
Dernier point mais non le moindre, pour imprimer en beauté le résultat de tout ce qui précède, vous pouvez insérer un onglet après le nom du répertoire et utiliser column
comme suit:
#!/bin/bash
shopt -s globstar
for i
do for k in **/"$i"*/
do date -d@$(stat -c%Y "$k") +"the folder $k%twas modified on %b %d %R"
done
done | column -ts$'\t'
$ tree
.
├── 1
│ └── 1
│ └── 1
├── 1something
└── 2
└── 1
$ bash -O globstar -c 'for i; do for k in **/"$i"*/; do stat -c "the folder %n was modified on %y" "$k"; done; done' _ 1
the folder 1/ was modified on 2018-06-07 09:45:28.098693507 +0200
the folder 1/1/ was modified on 2018-06-07 09:45:28.098693507 +0200
the folder 1/1/1/ was modified on 2018-06-07 09:45:28.098693507 +0200
the folder 1something/ was modified on 2018-06-07 09:55:36.066531665 +0200
the folder 2/1/ was modified on 2018-06-07 09:45:28.098693507 +0200
$ bash -O globstar -c 'for i; do for k in **/"$i"*/; do stat -c "the folder %n was modified on %y" "$k" | sed 's/:[^:]*$//'; done; done' _ 1
the folder 1/ was modified on 2018-06-07 09:45
the folder 1/1/ was modified on 2018-06-07 09:45
the folder 1/1/1/ was modified on 2018-06-07 09:45
the folder 1something/ was modified on 2018-06-07 09:55
the folder 2/1/ was modified on 2018-06-07 09:45
$ bash -O globstar -c 'for i; do for k in **/"$i"*/; do date -d@$(stat -c%Y "$k") +"the folder $k was modified on %b %d %R"; done; done' _ 1
the folder 1/ was modified on Jun 07 09:45
the folder 1/1/ was modified on Jun 07 09:45
the folder 1/1/1/ was modified on Jun 07 09:45
the folder 1something/ was modified on Jun 07 09:55
the folder 2/1/ was modified on Jun 07 09:45
$ bash -O globstar -c 'for i; do for k in **/"$i"*/; do date -d@$(stat -c%Y "$k") +"the folder $k%twas modified on %b %d %R"; done; done | column -ts'"$'\t'" _ 1
the folder 1/ was modified on Jun 07 09:45
the folder 1/1/ was modified on Jun 07 09:45
the folder 1/1/1/ was modified on Jun 07 09:45
the folder 1something/ was modified on Jun 07 09:55
the folder 2/1/ was modified on Jun 07 09:45
La commande find
peut faire ce dont vous avez besoin avec une seule ligne
Vous pouvez regarder l'action printf
dans find
Voirman find
pour plus de détails sur les paramètres de printf
Exemple
find /PATH/TO/SCAN -type d -iname '*pub*' -printf "%p %TY-%Tm-%Td %TH:%TM\n"
-type d : search for folders
-iname '*pub*' : find the pattern case insensitive
%p : display path of found folder
%TY : time Year
%Tm : time month
%Td : time day
%TH : time hour
%TM : time minutes
%TS : time seconds
Pour plus d'informations
Page Web officielle pour GNU find
25 exemples pratiques de la commande find
Voici une légère variation, qui utilise -regex
au lieu de -names
:
find . -type d -regex ".*\($1\).*$" -printf 'The folder %P was modified on %Tb %Td %TH:%TM\n'
Cela peut être un script d'une seule ligne ou, mieux encore, une fonction. Appelez ça comme ça:
./Finder.sh 'Vid\|Doc'
Cela rend l’approche plus idiomatique, comme grep
-.