Renommer plusieurs fichiers sous Unix
il y a plusieurs fichiers dans un répertoire qui commencent par le préfixe fgh
, par exemple:
fghfilea
fghfileb
fghfilec
je veux les renommer tous en commençant par le préfixe jkl
. Est-il une seule commande pour le faire au lieu de le renommer chaque fichier individuellement?
20 réponses
il y a plusieurs façons, mais l'utilisation de rename
sera probablement la plus facile.
utilisant une version de rename
:
rename 's/^fgh/jkl/' fgh*
utilisant une autre version de rename
(identique à la réponse de Judy2K ):
rename fgh jkl fgh*
vous devriez consulter la page de manuel de votre plate-forme pour voir laquelle des réponses ci-dessus s'applique.
C'est ainsi que sed
et mv
peuvent être utilisés ensemble pour faire renommer:
for f in fgh*; do mv "$f" $(echo "$f" | sed 's/^fgh/jkl/g'); done
comme dans le commentaire ci-dessous, si les noms de fichiers ont des espaces, les guillemets peuvent avoir besoin de surround la sous-fonction qui renvoie le nom pour déplacer les fichiers vers:
for f in fgh*; do mv "$f" "$(echo $f | sed 's/^fgh/jkl/g')"; done
rename pourrait ne pas être dans tous les systèmes. donc si vous ne l'avez pas, utilisez la coquille cet exemple dans shell bash
for f in fgh*; do mv "$f" "${f/fgh/xxx}";done
il y a plusieurs façons de le faire (toutes ne fonctionneront pas sur tous les systèmes unixy):
-
ls | cut -c4- | xargs -I§ mv fgh§ jkl§
le § peut être remplacé par tout ce qui vous convient. Vous pouvez faire cela avec
find -exec
aussi, mais qui se comporte subtilement différent sur de nombreux systèmes, donc j'évite généralement que -
for f in fgh*; do mv "$f" "${f/fgh/jkl}";done
brut mais efficace comme on dit
-
rename 's/^fgh/jkl/' fgh*
très joli, mais rename n'est pas présent sur BSD, qui est le système unix le plus commun afaik.
-
rename fgh jkl fgh*
-
ls | perl -ne 'chomp; next unless -e; $o = $_; s/fgh/jkl/; next if -e; rename $o, $_';
si vous insistez pour utiliser Perl, mais qu'il n'y a pas de renommage sur votre système, vous pouvez utiliser ce monstre.
Certains de ceux qui sont un peu compliquées et la liste est loin d'être complète, mais vous trouverez ce que vous voulez ici, pour à peu près tous les systèmes unix.
utilisant find
, xargs
et sed
:
find . -name "fgh*" -type f -print0 | xargs -0 -I {} sh -c 'mv "{}" "$(dirname "{}")/`echo $(basename "{}") | sed 's/^fgh/jkl/g'`"'
c'est plus complexe que la solution de @nik mais elle permet de renommer les fichiers de façon récursive. Par exemple, la structure,
.
├── fghdir
│ ├── fdhfilea
│ └── fghfilea
├── fghfile\ e
├── fghfilea
├── fghfileb
├── fghfilec
└── other
├── fghfile\ e
├── fghfilea
├── fghfileb
└── fghfilec
serait transformé en ceci,
.
├── fghdir
│ ├── fdhfilea
│ └── jklfilea
├── jklfile\ e
├── jklfilea
├── jklfileb
├── jklfilec
└── other
├── jklfile\ e
├── jklfilea
├── jklfileb
└── jklfilec
la clé pour qu'il fonctionne avec xargs
est de invoquer le shell de xargs .
pour installer le Perl renommer script:
sudo cpan install File::Rename
Il y a deux renomme , comme mentionné dans les commentaires en Stephan202 de réponse.
Les distributions basées sur Debian ont le renommé Perl . Les distributions Redhat/rpm ont le c renommé .
OS X n'en a pas installé par défaut (au moins en 10.8), pas plus que Windows/Cygwin.
sur Solaris vous pouvez essayer:
for file in `find ./ -name "*TextForRename*"`; do
mv -f "$file" "${file/TextForRename/NewText}"
done
#!/bin/sh
#replace all files ended witn .f77 to .f90 in a directory
for filename in *.f77
do
#echo $filename
#b= echo $filename | cut -d. -f1
#echo $b
mv "${filename}" "${filename%.f77}.f90"
done
Voici une façon de le faire en utilisant le Groovy en ligne de commande:
groovy -e 'new File(".").eachFileMatch(~/fgh.*/) {it.renameTo(it.name.replaceFirst("fgh", "jkl"))}'
je recommande d'utiliser mon propre script, ce qui résout ce problème. Il a également des options pour changer l'encodage des noms de fichiers, et de convertir la combinaison diacritiques en caractères précomposés, un problème que j'ai toujours lorsque je copie des fichiers à partir de mon Mac.
à l'Aide StringSolver outils (windows & Linux, bash) qui traitent par des exemples:
filter fghfilea ok fghreport ok notfghfile notok; mv --all --filter fghfilea jklfilea
It first calcule un filtre basé sur les exemples , où l'entrée est les noms de fichier et la sortie (ok et notok, chaînes arbitraires). Si filter avait l'option -- auto ou était invoqué seul après cette commande, il créerait un dossier ok
et un dossier notok
et pousserait les fichiers respectivement vers eux.
ensuite, en utilisant le filtre, la commande mv
est un mouvement semi-automatique qui devient automatique avec le modificateur --auto. En utilisant le filtre précédent grâce à --filter, il trouve une correspondance de fghfilea
à jklfilea
et l'applique ensuite sur tous les fichiers filtrés.
autres solutions monoligne
autres façons équivalentes de faire la même chose (chaque ligne est équivalente), donc vous pouvez choisir votre façon préférée de le faire.
filter fghfilea ok fghreport ok notfghfile notok; mv --filter fghfilea jklfilea; mv
filter fghfilea ok fghreport ok notfghfile notok; auto --all --filter fghfilea "mv fghfilea jklfilea"
# Even better, automatically infers the file name
filter fghfilea ok fghreport ok notfghfile notok; auto --all --filter "mv fghfilea jklfilea"
Multi-étapes " solution
pour trouver soigneusement si les commandes fonctionnent bien, vous pouvez taper ce qui suit:
filter fghfilea ok
filter fghfileb ok
filter fghfileb notok
et quand vous êtes sûr que le filtre est bon, effectuer le premier mouvement:
mv fghfilea jklfilea
si vous voulez tester, et utiliser le précédent filtre, tapez:
mv --test --filter
si la transformation n'est pas ce que vous vouliez (par exemple, même avec mv --explain
vous voyez que quelque chose ne va pas), vous pouvez taper mv --clear
pour redémarrer des fichiers en mouvement, ou ajouter d'autres exemples mv input1 input2
où input1 et input2 sont d'autres exemples
quand vous êtes sûr de vous, tapez juste
mv --filter
et voilà! Tout le renommage est fait en utilisant le filtre.
Avertissement: je suis un co-auteur de cet ouvrage fait à des fins académiques. Il peut également être un coup produisant fonction prochainement.
il était beaucoup plus facile (sur mon Mac) de faire cela à Ruby. Voici 2 Exemples:
# for your fgh example. renames all files from "fgh..." to "jkl..."
files = Dir['fgh*']
files.each do |f|
f2 = f.gsub('fgh', 'jkl')
system("mv #{f} #{f2}")
end
# renames all files in directory from "021roman.rb" to "021_roman.rb"
files = Dir['*rb'].select {|f| f =~ /^[0-9]{3}[a-zA-Z]+/}
files.each do |f|
f1 = f.clone
f2 = f.insert(3, '_')
system("mv #{f1} #{f2}")
end
à l'Aide renommeur de fichiers :
$ renamer --find /^fgh/ --replace jkl * --dry-run
supprimer le drapeau --dry-run
une fois que vous êtes heureux la sortie semble correcte.
ma version de renommer les fichiers de masse:
for i in *; do
echo "mv $i $i"
done |
sed -e "s#from_pattern#to_pattern#g” > result1.sh
sh result1.sh
cela a fonctionné pour moi en utilisant regexp:
je voulais que les fichiers soient renommés comme ceci:
file0001.txt -> 1.txt
ofile0002.txt -> 2.txt
f_i_l_e0003.txt -> 3.txt
on utilise le [a-z|_]+0*([0-9]+. ) regexp où ([0-9]+. ) est un substrat de groupe à utiliser sur la commande
"ls -1 | awk 'match("151910920", /[a-z|\_]+0*([0-9]+.*)/, arr) { print arr[0] " " arr[1] }'|xargs -l mv
produit:
mv file0001.txt 1.txt
mv ofile0002.txt 2.txt
mv f_i_l_e0003.txt 3.txt
autre exemple:
file001abc.txt -> abc1.txt
ofile0002abcd.txt -> abcd2.txt
ls -1 | awk 'match("151930920", /[a-z|\_]+0*([0-9]+.*)([a-z]+)/, arr) { print arr[0] " " arr[2] arr[1] }'|xargs -l mv
produit:
mv file001abc.txt abc1.txt
mv ofile0002abcd.txt abcd2.txt
Avertissement, être prudent.
j'ai écrit ce script pour chercher tout .fichiers mkv renommage récursif des fichiers trouvés .avi. Vous pouvez le personnaliser à votre neeeds. J'ai ajouté d'autres choses comme obtenir le répertoire de fichier, l'extension, le nom de fichier à partir d'un chemin de fichier juste incase vous devez vous référer à quelque chose dans le futur.
find . -type f -name "*.mkv" | while read fp; do
fd=$(dirname "${fp}");
fn=$(basename "${fp}");
ext="${fn##*.}";
f="${fn%.*}";
new_fp="${fd}/${f}.avi"
mv -v "$fp" "$new_fp"
done;
un script générique pour lancer une expression sed
sur une liste de fichiers (combine la sed
solution avec la rename
solution ):
#!/bin/sh
e=
shift
for f in $*; do
fNew=$(echo "$f" | sed "$e")
mv "$f" "$fNew";
done
invoquer en passant le script une expression sed
, et puis n'importe quelle liste de dossiers, juste comme une version de rename
:
script.sh 's/^fgh/jkl/' fgh*
vous pouvez également utiliser script ci-dessous. il est très facile à exécuter sur le terminal...
//Renommer plusieurs fichiers à la fois
for file in FILE_NAME*
do
mv -i "${file}" "${file/FILE_NAME/RENAMED_FILE_NAME}"
done
exemple: -
for file in hello*
do
mv -i "${file}" "${file/hello/JAISHREE}"
done