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?

186
demandé sur codeforester 2009-07-06 15:21:39

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.

239
répondu Stephan202 2017-05-23 11:54:59

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
95
répondu nik 2017-07-25 08:27:13

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
66
répondu ghostdog74 2009-07-07 02:22:44

par mmv :

mmv "fgh*" "jkl#1"
34
répondu Lee Netherton 2013-11-21 11:17:37

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.

17
répondu iwein 2012-10-12 09:41:50
rename fgh jkl fgh*
10
répondu Judy2K 2009-07-06 11:28:19

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 .

7
répondu luissquall 2017-05-23 10:31:37

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.

3
répondu Sam Inverso 2013-05-14 14:02:27

sur Solaris vous pouvez essayer:

for file in `find ./ -name "*TextForRename*"`; do 
    mv -f "$file" "${file/TextForRename/NewText}"
done
2
répondu Andrei Aleksandrov 2014-12-23 11:41:05
#!/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
2
répondu Suragini 2018-08-22 04:54:10

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"))}'
1
répondu jesseplymale 2013-08-06 16:47:37

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.

https://github.com/kugland/rename.pl/blob/master/rename.pl

1
répondu André von Kugland 2013-11-01 11:26:53

à 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.

1
répondu Mikaël Mayer 2014-01-31 13:51:35

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
1
répondu Raymond Gan 2014-05-11 10:04:00

à 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.

1
répondu Lloyd 2018-07-18 09:31:29

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
1
répondu mdev 2018-08-22 04:50:32

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.

0
répondu Steven Lizarazo 2016-05-06 20:38:09

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;
0
répondu David Okwii 2016-05-29 16:29:14

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*
0
répondu palswim 2017-05-23 10:31:37

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
0
répondu Sanjay Singh 2017-02-15 13:31:10