trouver avec -execdir
Quand je cours find
avec -execdir
Je n'ai pas les résultats que je m'attendais.
Par exemple:
mkdir -p a/b/c
find . -type d -execdir touch foo \;
$ tree a
a
├── b
│ ├── c
│ └── foo
└── foo
Répertoire c
ne contient pas de fichier foo
. Comment puis-je obtenir find
pour visiter et faire quelque chose localement dans chaque répertoire?
Pour chaque fichier correspondant (c'est-à-dire chaque répertoire), find
passe au répertoire qui le contient (c'est-à-dire son répertoire parent) et exécute la commande spécifiée. Étant donné que la commande n'utilise pas le nom du match, il ne va jamais agir sur tous les répertoires. Pour cet arbre de répertoire particulier, vous faites
(cd . && touch foo) # because ./a matches
(cd ./a && touch foo) # because ./a/b matches
(cd ./a/b && touch foo) # because ./a/b/c matches
Pour créer un fichier dans chaque répertoire, vous pouvez simplement utiliser -exec
à la place de -execdir
, à condition que votre implémentation de find
permet {}
À l'intérieur d'un argument (le plus, je pense que tous ceux):
find . -type d -exec touch {}/foo +
Pour la portabilité POSIX, vous aurez besoin de l'assemblage du nom du répertoire et du nom de base du fichier manuellement.
find . -type d -exec sh -c 'touch "$0/foo"' {} \;
ou (légèrement plus rapide)
find . -type d -exec sh -c 'for d; do touch "$d/foo"; done' _ {} +
Vous pouvez également utiliser la correspondance générique de faune récursive de Bash. Méfiez-vous que (contrairement à la fonctionnalité correspondante en KSH et à ZSH, et contrairement à votre commande find
_ commande) Bash recoque sous des liens symboliques vers des répertoires.
shopt -s globstar
for d in **/*/; do touch -- "$d/foo"; done
Une solution ZSH:
touch ./**/(e\''REPLY+=foo'\')
La commande s'exécute dans chaque répertoire contenant un fichier correspondant. Etant donné que c
ne contient pas de répertoire, il ne correspond pas et ne sera donc pas exécuté là-bas.
La solution consiste à ajouter le nom du répertoire à l'argument Execdir, comme:
find . -type d -execdir touch {}/foo \;
De man file
-execdir command {} +
Like -exec, but the specified command is run from the subdirectory containing the matched file
Votre répertoire correspondant c
vit dans le répertoire b
, de sorte que l'exécutif est exécuté. Cela fonctionnerait comme vous vous attendez si vous recherchez des fichiers au lieu de répertoires.
Vous pouvez probablement réaliser ce que vous voulez en envoyant les répertoires à xargs
comme cela sera fourni la liste complète des répertoires.