2009-05-11 10 views
2

Comment renommer tous les fichiers d'un répertoire en un nouveau nom en utilisant la commande mv. Répertoire a 1000s de fichiers et l'exigence est de changer le dernier caractère de chaque nom de fichier à un char spécifique. Exemple: les fichiers sontRenommer par lots pour ne changer qu'un seul caractère

abc.txt 
asdf.txt 
zxc.txt 
... 
ab_.txt 
asd.txt 

il devrait changer de

ab_.txt 
asd_.txt 
zx_.txt 
... 
ab_.txt 
as_.txt 
+1

Ce n'est pas quelque chose que 'mv' lui-même peut faire. Vous allez devoir le programmer, probablement en utilisant des scripts shell. Ainsi, il serait utile de spécifier * quel * shell vous essayez de résoudre ce problème, car les scripts diffèrent entre les shells. – unwind

Répondre

0

Je ne sais pas si cela va fonctionner avec des milliers de fichiers, mais bash:

for i in *.txt; do 
    j=`echo $i |sed 's/.\.txt/_.txt/'` 
    mv $i $j 
done 
0

Si vos fichiers tous ont un suffixe .txt, je suggère le script suivant:

for i in *.txt 
do 
    r=`basename $i .txt | sed 's/.$//'` 
    mv $i ${r}_.txt 
done 
+0

Cela ne semble pas remplacer la lettre avant le point avec le trait de soulignement. – unwind

+0

Je ne savais pas vraiment que basename pouvait le faire (merci pour l'éducation), mais la solution est imparfaite - elle ajoute le trait de soulignement plutôt que de remplacer le dernier caractère. – paxdiablo

+0

Oui, vous avez raison. Je modifie en gardant intentionnellement le nom de base. – mouviciel

2

Vous devez surveiller les collisions de nom, mais cela devrait fonctionner bien:

for i in *.txt ; do 
    j=$(echo "$i" | sed 's/..txt$/_.txt/') 
    echo mv \"$i\" \"$j\" 
    #mv "$i" "$j" 
done 

après vous décommentez mv (je l'ai laissé commenta pour que vous puissiez voir ce qu'il fait en toute sécurité). Les citations sont pour manipuler des fichiers avec des espaces (mal, choses viles à mon avis :-).

0

Vous pouvez utiliser l'opérateur de bash ${parameter%%word} ainsi:

for FILE in *.txt; do 
    mv $FILE ${FILE%%?.txt}_.txt 
done 
1

Recherche devrait être plus efficace que for file in *.txt, qui étend l'ensemble de vos 1000 fichiers dans une longue liste de paramètres de ligne de commande. Exemple (mis à jour pour utiliser l'approche de remplacement bash):

find . \(-type d ! -name . -prune \) -o \(-name "*.txt" \) | while read file 
do 
    mv $file ${file%%?.txt}_.txt 
done 
1

Est-ce une exigence précise que vous utilisez la commande mv?
L'utilitaire perl rename a été écrit pour ce genre de chose. C'est la norme pour les distributions linux basées sur debian, mais selon this page il peut être ajouté très facilement à n'importe quel autre.

Si elle est déjà là (ou si vous l'installez) vous pouvez faire:

rename -v 's/.\.txt$/_\.txt/' *.txt 

La page inclus ci-dessus a quelques informations de base sur les regex et les choses si elle est nécessaire.

2

Si tous les fichiers se terminent par "txt", vous pouvez utiliser mmv (Multiple Move) pour que:

mmv "*[a-z].txt" "#1_.txt" 

Plus: mmv vous dira quand cela génère une collision (dans votre exemple: abc. txt devient ab_.txt qui existe déjà) avantun fichier est renommé.

Notez que vous devez citer les noms de fichiers, sinon le shell développera la liste avant que mmv le voit (mais mmv va généralement attraper cette erreur, aussi).