Comment puis-je travailler récursivement à travers une arborescence de répertoires et exécuter une commande spécifique sur chaque fichier, et sortir le chemin, le nom de fichier, l'extension, la taille du fichier et un autre texte spécifique dans un seul fichier dans bash.
14
Réponses:
Alors que les
find
solutions sont simples et puissantes, j'ai décidé de créer une solution plus compliquée, basée sur cette fonction intéressante , que j'ai vue il y a quelques jours.1. Créez un fichier script exécutable, appelé
walk
, qui est situé dans/usr/local/bin
pour être accessible en tant que commande shell:nano
: Shift+ Insertpour coller; Ctrl+ Oet Enterpour économiser; Ctrl+ Xpour sortir.2. Le contenu du script
walk
est:3. Explication:
Le mécanisme principal de la
walk()
fonction est assez bien décrit par Zanna dans sa réponse . Je ne décrirai donc que la nouvelle partie.Dans la
walk()
fonction, j'ai ajouté cette boucle:Cela signifie que pour chacun
$entry
qui est un fichier sera exécuté la fonctionfile_specification()
.La fonction
file_specification()
comporte deux parties. La première partie obtient les données relatives au fichier - nom, chemin, taille, etc. La deuxième partie génère les données sous une forme bien formatée. Pour formater les données, on utilise la commandeprintf
. Et si vous souhaitez modifier le script, vous devriez lire à propos de cette commande - par exemple cet article .La fonction
file_specification()
est un bon endroit où vous pouvez placer la commande spécifique qui doit être exécutée pour chaque fichier . Utilisez ce format:Ou vous pouvez enregistrer la sortie de la commande en tant que variable, puis
printf
cette variable, etc.:Ou directement
printf
la sortie de la commande:La section à la mendicité, appelée
Colourise the output
, initialise quelques variables utilisées dans laprintf
commande pour coloriser la sortie. Vous trouverez plus d'informations à ce sujet ici .Au bas du script est ajoutée une condition supplémentaire qui traite des chemins absolus et relatifs.
4. Exemples d'utilisation:
Pour exécuter
walk
pour le répertoire actuel:Pour exécuter
walk
pour n'importe quel répertoire enfant:Pour exécuter
walk
pour tout autre répertoire:Pour créer un fichier texte, basé sur la
walk
sortie:Pour créer un fichier de sortie sans codes couleur ( source ):
5. Démonstration d'utilisation:
la source
Je suis un peu perplexe quant à la raison pour laquelle personne ne l'a encore posté, mais a effectivement
bash
des capacités récursives, si vous activez l'globstar
option et utilisez**
glob. En tant que tel, vous pouvez écrire unbash
script (presque) pur qui utilise cette globstar récursive comme ceci:Notez que nous utilisons ici l'expansion des paramètres pour obtenir les parties du nom de fichier que nous voulons et que nous ne comptons pas sur des commandes externes, sauf pour obtenir la taille du fichier avec
du
et nettoyer la sortie avecawk
.Et pendant qu'il parcourt votre arborescence de répertoires, votre sortie devrait ressembler à ceci:
Les règles standard d'utilisation des scripts s'appliquent: assurez-vous qu'il est exécutable avec
chmod +x ./myscript.sh
et exécutez-le à partir du répertoire actuel via./myscript.sh
ou placez-le dans~/bin
et exécutezsource ~/.profile
.la source
"$(file "$i")"
(dans le script ci-dessus en tant que deuxième partie d'un printf) retourneraient?output the path, filename, extension, filesize
, donc la réponse correspond à ce qui est demandé. :)Vous pouvez utiliser
find
pour faire le travailCela vous aidera si vous souhaitez simplement répertorier tous les fichiers avec leur taille.
-exec
vous permettra d'exécuter une commande ou un script personnalisé pour chaque fichier\;
utilisé pour analyser les fichiers un par un, vous pouvez les utiliser+;
si vous souhaitez les concaténer (signifie les noms de fichiers).la source
Avec
find
seulement.Ou, vous pouvez utiliser ci-dessous à la place:
la source
find -printf
). +1Si vous connaissez la profondeur de l'arbre, le moyen le plus simple sera d'utiliser le caractère générique
*
.Écrivez tout ce que vous voulez faire en tant que script shell ou fonction
puis exécutez
for i in *; do thing "$i"; done
,for i in */*; do thing "$i"; done
... etcDans votre fonction / script, vous pouvez utiliser des tests simples pour identifier les fichiers avec lesquels vous souhaitez travailler et faire tout ce dont vous avez besoin avec eux.
la source
$i
.for i in */*
marche. Ici, testez-le:for i in */*; do printf "|%s|\n" "$i"; done
find
peut le faire:Jettes un coup d'oeil à
man find
d'autres propriétés de fichier.Si vous avez vraiment besoin de l'extension, vous pouvez ajouter ceci:
la source