Renommer des fichiers sous Linux avec une expression régulière

9

J'avais un groupe de fichiers que je voudrais renommer régulièrement, les fichiers sont nommés des choses comme

"System-Log-01-01-2009-NODATA.txt"
"Something-Log-01-01-2009-NODATA.txt"

Et je les voulais en minuscules, aaaammjj, extension .log

"system.20090101.log"
"something.20090101.log"
Osama ALASSIRY
la source

Réponses:

14

J'avais l'habitude d'écrire des scripts Perl pour ce faire, jusqu'à ce que je découvre la commande rename.

Il accepte une expression rationnelle perl pour effectuer le changement de nom:

pour cela, je viens de taper deux commandes:

rename 's/(\w+)-(\w+)-(\d\d)-(\d{4})-NODATA.txt\$1.$4$3$2.log$//' *
rename 'y/A-Z/a-z/' *.log

Pour certaines distributions, cependant, renamen'a pas cette fonctionnalité (voir sa page de manuel), et vous devrez peut-être installer perl-renameou prename.

Osama ALASSIRY
la source
très belle réponse
Judioo
8
Attention, certaines distributions livrent une commande de changement de nom sans valeur. Vérifiez celui que votre distribution a en premier.
derobert
Je le savais mmvmais finalement grâce à renameje peux utiliser le pouvoir des regex
Ludovic Kuty
5
Sur Arch Linux, c'est perl-rename.
Oleh Prypin
6

Comme je n'ai pas de commande renommer, je m'appuie sur ceci:

for myfile in /my/folder/*; do
    target=$(echo $myfile|sed -e 's/foo/bar/g')
    mv "$myfile" "$target"
done
Franz Bettag
la source
5

mmv est un utilitaire linux standard pour déplacer / renommer plusieurs fichiers. Il est disponible à partir des dépôts pour la plupart des distributions. Pour votre exemple ci-dessus, vous pouvez faire:

mmv *-Log-*-*-*-NODATA.txt #l1.#4#3#2.log

Pour plus d'informations, lisez cet article debaday ou la page de manuel .

Hamish Downer
la source
5

renamel'utilité n'est pas très "standard". Chaque distribution est livrée avec un renameoutil différent . Par exemple, ici sur Gentoo, renamevient du sys-apps/util-linuxpackage et ne prend pas en charge l'expression régulière.

Hamish Downer a suggéré que mmvcela semble utile, spécialement pour une utilisation dans des scripts.

En revanche, pour le cas général, vous voudrez peut-être renameutils . Il a qmvet des qcpcommandes, qui ouvriront un éditeur de texte de votre choix (ma préférence: Vim) et vous permettront d'y éditer les noms de fichiers de destination. Après avoir enregistré et fermé l'éditeur, qmv/ qcpfera tout le changement de nom.

Les deux mmvet qmvsont assez intelligents pour renommer les fichiers dans l' ordre correct et aussi pour détecter les renommages circulaires, et sera automatiquement créer un fichier temporaire si nécessaire.

Denilson Sá Maia
la source
Sur Gentoo, vous pouvez également faire émerger le sys-apps/renamepackage, qui vous renamexmpermet de renommer les expressions régulières ainsi que les majuscules / minuscules de masse et d'autres choses intéressantes.
radicand
1

Être juste:

rename 's/(\w+)-(\w+)-(\d\d)-(\d{4})-NODATA.txt\$1.$4$3$2.log$//' *.txt

donne cette sortie:

Use of uninitialized value $4 in regexp compilation at (eval 1) line 1.
Use of uninitialized value $3 in regexp compilation at (eval 1) line 1.
Use of uninitialized value $2 in regexp compilation at (eval 1) line 1.

Mais:

rename -n 's/(\w+)-\w+-(\d{2})-(\d{2})-(\d{4})-NODATA\.txt$/$1.$4$3$2\.log/' *.txt && rename 'y/A-Z/a-z/' System.20090101.log

donne la bonne sortie:

System-Log-01-01-2009-NODATA.txt renamed as System.20090101.log
System.20090101.log renamed as system.20090101.log

remplacement du commutateur {-n} par {-v}

fpba
la source
1

J'ai créé un petit script bash pour ce faire:

#!/bin/bash

for f in `ls /path/to/folder`; do
  # Create new filename from the old one
  # This example replaces A (upper case) with a (lower case)
  new_file=`echo "$new_file" | tr A a`

  # Rename the file
  mv "$f" "$new_file"
done
bjarkig82
la source
En général, l'analyse des lssorties n'est pas la meilleure idée. Une recherche aléatoire a tiré cette longue lecture sur Unix. SE pour votre amusement. | De plus, votre réponse correspondrait mieux à la question avec untr '[:upper:]' '[:lower:]'
HBruijn