Au lieu de faire appel à des commandes externes, où vous perdez les informations sur le répertoire en cours, vous pouvez utiliser find
l’ -execdir
option permettant à ce dernier d’exécuter des commandes dans le répertoire dans lequel un fichier a été trouvé.
find . -name oldfile.txt -execdir mv -- {} newfile.txt \;
C’est en fait une version plus sécurisée -exec
qui est préférée dans la plupart des situations. Le seul inconvénient est que ce n'est pas spécifié par POSIX, donc vous ne le trouverez pas dans toutes les find
variantes - mais au moins dans GNU find
et BSD, find
vous le pouvez.
Si vous voulez être plus sûr, vous devriez appeler mv
comme mv -- source target
si un fichier commençant par un tiret n'était pas interprété incorrectement comme un argument mv
.
Si, pour une raison quelconque, vous ne souhaitez pas utiliser -execdir
ou avoir d'autres tâches compliquées, ou si vous souhaitez simplement en apprendre un peu plus sur Bash, voici comment obtenir le dossier et déplacer le fichier en fonction de cela:
find . -name oldfile.txt -exec bash -c 'mv -- "${0}" "$(dirname $0)"/newfile.txt' {} \;
Ici, {}
passe le chemin complet à bash
as $0
. Nous obtenons son nom de répertoire via commande substitution ( $(…)
), puis ajoutons le nouveau nom. L'argument d'origine et le nom du répertoire doivent être cités deux fois pour empêcher les espaces de rompre la commande - sinon, mv
on penserait que vous essayez de déplacer deux fichiers appelés foo
et bar
lorsque le fichier est réellement appelé foo bar
, par exemple.
mv
est le répertoire? Je n'ai jamais vu mv avoir un troisième param. J'ai regardé le manuel mais cela ne semble pas clair.mv
. Le\;
fait partie de la-exec
/ l'-execdir
option - voir lefind
manuel , je vous lié. Vous devez toujours l’inclure pour quefind
la fin de la commande spécifiée soit reconnueexec
.Both of these constructions need to be escaped (with a ‘\’) or quoted to protect them from expansion by the shell.
Cela signifie que cela{}
devrait également être évité.{}
, cela fonctionne également sans cela dans la plupart des interprétationsfind
. Citer{}
n'est nécessaire que s'il est interprété autrement par le shell, ce qui n'est généralement pas le cas. Je pense que @DanielBeck a récemment eu un problème avec lefish
shell et cela - mais je ne suis pas tout à fait sûr que cefish
soit la cause du problème.