Le find
La commande peut être utilisée de manière assez concise dans des cas simples où vous souhaitez effectuer des opérations sur des correspondances de noms de fichiers génériques (ou plus complexes). La technique ci-dessous peut être mémorisée... presque !
Cela fonctionne en laissant le find
commande exécuter une autre commande sur chaque nom de fichier qu'il trouve. Vous pouvez exécuter cet exemple à sec en utilisant echo
au lieu de/devant mv
.
Si nous voulions déplacer tous les fichiers du répertoire courant dont le nom commence par 'report', vers un autre répertoire parallèle appelé 'reports' :
find . -name "report*.*" -exec mv '{}' ../reports/ \;
La chaîne générique doit être entre guillemets, le {} marquant le nom de fichier qui a été "trouvé" doit être entre guillemets et le point-virgule final doit être échappé - tout cela en raison du traitement Bash/shell de ces caractères.
Regardez la page de manuel pour find
pour plus d'utilisations :https://linux.die.net/man/1/find
Parlons un peu du fonctionnement des caractères génériques.
cp *.txt foo
n'invoque pas réellement cp
avec un argument *.txt
, si des fichiers correspondant à ce glob existent. Au lieu de cela, il exécute quelque chose comme ceci :
cp a.txt b.txt c.txt foo
De même, quelque chose comme
mv *.txt *.old
... ne peut pas savoir quoi faire, car lorsqu'il est invoqué, ce qu'il voit est :
mv a.txt b.txt c.txt *.old
ou, pire, si vous avez déjà un fichier nommé z.old
, il verra :
mv a.txt b.txt c.txt z.old
Ainsi, vous devez utiliser différents outils. Considérez :
# REPLACES: mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err
for f in /data/*/Sample_*/logs/*_Data_time.err; do
mv "$f" "${f%_Data_time.err}_Data_time_orig.err"
done
# REPLACES: cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh
for f in /data/*/Sample_*/scripts/*.sh; do
cp "$f" "${f%.sh}_orig.sh"
done
# REPLACES: sh /data/*/Sample_*/scripts/*_orig.sh
for f in /data/*/Sample_*/scripts/*_orig.sh; do
if [[ -e "$f" ]]; then
# honor the script's shebang and let it choose an interpreter to use
"$f"
else
# script is not executable, assume POSIX sh (not bash, ksh, etc)
sh "$f"
fi
done
Cela utilise une extension de paramètre pour supprimer la fin de l'ancien nom avant d'ajouter le nouveau nom.