Comment renommer plusieurs fichiers dans un répertoire en même temps


12

J'ai un répertoire /var/tmp/abcqui contient 4 fichiers:

12345-ram-3e3r5-io9490-89adu9.csv
45434-dam-qwe35-to9490-43adu9.csv
11234-cam-yy3r5-ro9490-85adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv

Je veux renommer tous les fichiers CSV (trouver tous les fichiers et les renommer) de la manière la plus courte possible (probablement une ligne):

XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

Réponses:


15

rename -n 's/(\w+)/XXXXX/' *.csv

retirer le -nquand heureux.


2
Pour une version appropriée de rename. Je suppose que c'est Larry Wall rename, du renamepaquet dans Debian et dérivé (et IIRC prenamesur les systèmes de persuasion RedHat). Un outil très utile.
Xenoid

2
perl-renamedans arch linux
lesmana

1
@SHawarden, j'ai essayé d'exécuter la commande et de lire la partie pertinente de la page de manuel pour comprendre le modèle de remplacement, mais lors de l'ajout de l' verboseindicateur, il ne produit rien et n'effectue pas les changements de nom de fichier, même si le chemin actuel a fichiers avec des noms similaires à 12345_foo.csv. Dois-je effectuer une tâche supplémentaire pour le faire fonctionner (actuellement sur Fedora 30)? C'est une approche plus propre que le bouclage. Merci d'avance!
danieldeveloper001

3
@ danieldeveloper001 Avez-vous utilisé renameou prename? Voir mon commentaire ci-dessus. man {the command}liste les auteurs à la fin.
Xenoid

2
Cela ne fonctionne que sur les systèmes dérivés de Debian. Les systèmes dérivés de Fedora ont une renamecommande complètement différente ; voir unix.stackexchange.com/a/238862/135943
Wildcard

11

Essayer:

for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done

Comment ça fonctionne:

  • for f in *.csv; do

    Cela démarre une boucle sur tous les *.csvfichiers.

  • mv -i -- "$f" "XXXXX-${f#*-}"

    Cela renomme les fichiers comme vous le souhaitez, en demandant de manière interactive avant d'écraser un fichier.

  • done

    Cela marque la fin de la boucle.

Exemple:

$ ls -1
11234-cam-yy3r5-ro9490-85adu9.csv
12345-ram-3e3r5-io9490-89adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv
45434-dam-qwe35-to9490-43adu9.csv
$ for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done
$ ls -1
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

4

J'ai aimé le petit défi que vous avez publié, voici donc ma solution. Je suppose que tous vos fichiers commencent par 5 caractères numériques, donc utilisez la commande cut pour remplacer les fichiers numériques initiaux par "XXXXX".

Ci-dessous, les fichiers avant la commande.

-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 11111_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 12345_baz_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml

Ci-dessous, la commande one liner.

for src in *.csv; do dst=XXXXX$(echo $src| cut -c6-); mv $src $dst; done;

Ci-dessous, les fichiers après la commande.

-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 XXXXX_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 XXXXX_baz_file.csv

C'est ça que vous cherchez? :)

Les références:

Boucler la sortie de la commande dans bash

Sous-chaînes en bash


2
Bash peut faire ce genre de manipulation de chaîne, pas besoin de bifurquer un nouveau processus pour chacun, veuillez l'autre réponse sur la façon dont.
chx

1
@chx, a déjà vu les autres réponses et en a acquis un peu de connaissances, mais merci de les avoir signalées. Pourriez-vous nous en dire plus no need to fork a new process for each?
danieldeveloper001

3
cutest un binaire ( /usr/bin/cut) distinct et son exécution consomme plus de ressources que l'utilisation de shell intégrés.
chx

2
Je vois, cela compte vraiment si l'intention est de renommer un grand nombre de fichiers. Merci pour la clarification!
danieldeveloper001

1

pas de fourches:

ls | perl -lne '$suf=substr($_,6); rename $_, "XXXXX-$suf"'

Lorsque vous utilisez une boucle shell, les mvfourches une fois par fichier. La renamecommande de Perl ne fonctionne pas.

(La commande renommer de Perl a certaines restrictions, mais dans ce cas spécifique, ces restrictions ne s'appliquent pas.)

En ce qui concerne la renamecommande ci-dessus, oui, cela fonctionne, mais vous avez alors toute cette confusion entre deux types de renommage différents, etc. Si vous avez le bon, parfait, mais sinon, cela fonctionne aussi.

Si vous n'avez pas la commande perl-rename et ne pouvez pas l'installer, vous pouvez simplement faire ceci:

ls | perl -lne '$old=$_; s/(\w+)/XXXXX/; rename $old, $_'

Comme vous pouvez le voir, cela utilise la même substitution que celle indiquée dans la réponse du haut. Bien sûr, le perl-rename a d'autres cloches et sifflets (la première réponse mentionnée, -ndéjà, puis il y a -0, -fet ainsi de suite), et plus vous en avez besoin, plus vous devez installer cela au lieu de lancer le vôtre de cette manière .


Les implémentations habituelles d'un tuyau auront des fourches.
muru

Je voulais dire, "ne va pas bifurquer une fois par fichier à renommer", contrairement même au shell, où le "mv" se trouve à fourches / usr / bin / mv ou autre. En effet, la commande "rename" est une commande interne perl qui appelle directement rename () dans libc. Bien sûr, il a certaines restrictions, mais dans cet exemple spécifique, ces restrictions ne s'appliquent pas.
sitaram

1
Cela est également vrai de la renamecommande ( première réponse , utilise également Perl), alors vous devriez peut-être ajouter un peu plus d'explications que simplement "pas de fourches" à la réponse.
muru
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.