Trouver et remplacer le nom de fichier dans un répertoire de façon récursive
Je veux renommer tous les fichiers dans un dossier qui commence avec 123_xxx.txt
à xxx.txt
.
Par exemple, mon répertoire:
123_xxx.txt
123_yyy.txt
123_zzz.txt
I want to rename all files as:
xxx.txt
yyy.txt
zzz.txt
J'ai vu quelques scripts bash dans ce forum, mais je suis toujours confus comment l'utiliser pour mon exigence.
Nous supposons que j'utilise:
for file in `find -name '123_*.txt'` ; do mv $file {?.txt} ; done
Est-ce la bonne façon de le faire?
Vous devez vous connecter pour publier un commentaire.
Faire de cette façon:
Avantages:
find . -name '123*.txt' -type f -exec bash -c 'mv "$1" "${1/\/123_/hello/}"' -- {} \;
-c
à l'intérieur des citations est en fait un script bash et interprété comme tel. La suite--
est arbitraire et est utilisé par de bash comme "nom de fichier" pour le oneliner script. Le{}
est la syntaxefind
utilise comme un espace réservé pour chaque nom de fichier et\;
ditfind
que cela se termine le-exec
option. Vous devriez vraimentman find
et de lire sur-exec
, puis regardez dans les scripts shell, en commençant parman bash
et en regardant la-c
option.find . -name '*companyA*' -type f -exec bash -c 'mv "$1" "${1/\/companyA/companyB/}"' -- {} \;
. Mais arriver:mv: `./companyA-2015-10-01' and `./companyA-2015-10-01' are the same file
\/companyA
partie). Vous aurez besoin de créer une autre question pour ce ou de travailler avec un expert de manière interactive via un autre canal de communication.\/
et le dernier/
étaient inutiles. Donc"${1/companyA/companyB}"
bien fonctionné.${var//Pattern/Replacement}
${var//patter/replacement}
est bon à savoir, mais si le terme de recherche se produit dans les noms de fichier et répertoire puis il est encore difficile à résoudre. Je ne peut pas utiliser de//
de remplacement au-dessus de "trouver" de commande, puis-je? Euh... je vais aller expérimenter...touch catdog; find * -name "*dog" -exec bash -c 'echo $1 foobar' -- {} \;
imprimecatdog foobar
. Maintenant, essayez sansfind
,bash -c 'echo $1 foobar' -- catdog
imprime toujourscatdog foobar
de le faire. Pas de AWK, pas pour, pas de xargs nécessaire, mais renommer, une commande très utile à partir de la lib Perl. Il n'est pas toujours fourni avec Linux, mais est facile à installer à partir du repos.
awk
et en boucle les réponses ci-dessus pour ceux qui ont le perlrename
.brew install rename
sur Macrename 's/^123_//' *
et il va faire exactement la même chose. Des acclamations.globstar
mis en bash (shopt -s globstar
), vous pouvez le faire de manière récursive:rename 's/^123_//' **/*
vous pouvez cocher la case 'renommer' outil
par exemple
ou (gawk est nécessaire)
test:
rename
l'exemple n'est pas récursive. Lefind
exemple est, mais il inutilement, ne pas utiliserrename
pour le renommage. Et il des tuyaux d'un script généré àsh
, ce qui est dégueulasse.Dans le cas où vous souhaitez remplacer la chaîne de caractères dans un nom de fichier appelé foo bar, vous pouvez l'utiliser sous linux ubuntu, changement de type de fichier pour vos besoins
Une légère variation sur Kent qui ne nécessite pas rester bouche bée et est un peu plus lisible (même si, c'est discutable..)
find . -name "123*" | awk '{a=$1; gsub(/123_/,""); printf "mv \"%s\" \"%s\"\n", a, $1}' | sh
À condition que vous n'avez pas de retours à la ligne dans vos noms de fichiers:
Pour vraiment un moyen sûr, à condition que votre
find
prend en charge la-print0
drapeau (GNUfind
n'):De s'étendre sur les Sorpigal la réponse de, si vous souhaitez remplacer le
123_
avechello_
, vous pouvez utiliserVous pouvez faire un petit script bash pour que.
Créez un fichier nommé
recursive_replace_filename
avec ce contenu :Rendre exécutable fonctionne:
Noter que ce script peut être dangereux, assurez-vous de savoir ce qu'il fait et dans quel dossier vous êtes l'exécuter, et avec quels arguments. Dans ce cas, tous les fichiers dans le dossier en cours, de manière récursive, contenant
123_
sera renommé.À l'aide de renommer de util-linux 2.28.2 j'ai dû utiliser un autre syntaxt:
Essayé la réponse ci-dessus, mais il ne fonctionne pas pour moi, j'étais la chaîne à l'intérieur des dossiers et des noms de fichiers en même temps, donc voici ce que j'ai fait le script bash suivant:
D'abord j'ai commencé par le remplacement, à l'intérieur le nom des dossiers à l'intérieur de nom de fichiers.
Si les noms sont fixes, vous pouvez visiter chaque répertoire et effectuer le changement de nom dans un shell interne est exécuté (pour éviter de changer le répertoire courant) assez simplement. C'est de cette façon j'ai renommé un tas de
new_paths.json
fichiers à chaquepaths.json
:en utilisant les exemples ci-dessus, j'ai utilisé ce pour remplacer une partie du nom de fichier... il a été utilisé pour renommer les différents fichiers de données dans un répertoire, en raison d'un vendeur en changeant les noms.
find . -name 'o3_cloudmed_*.*' -type f -exec bash -c 'mv "$1" "${1/cloudmed/revint}"' -- {} \;
Voir prename officiel de l'Perl5 wiki. Copie pour votre confort:
prename
- Un script qui renomme les fichiers selon une expression régulière. (Où est l'original publié?) Initialement nommé renommer, on le trouve surtout que prename parce que l'original de l'un des affrontements avec la commande renommer duutil-linux
paquet. De nombreuses fourches et reimplementations:prename
, mais ce n'est pas récursive.