web-dev-qa-db-fra.com

shell pour imprimer la date de modification de tous les répertoires

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: enter image description here 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 
4
Muh

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.

6
muru

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'

Exemple d'exécution

$ 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
5
dessert

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

4
cmak.fr

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-.

2