web-dev-qa-db-fra.com

Existe-t-il une commande linux comme mv mais avec regex?

Par exemple, je veux mv (.*?).sql $1.php,

existe-t-il une commande qui me permet de spécifier des modèles de changement de nom?

39
JoshRibs

Comme d'autres l'ont déjà mentionné, rename est bon, mais lisez la page de manuel (man rename) avant de l'essayer. Il existe au moins deux outils entièrement différents appelés rename et celui que vous avez dépend de votre distribution. Les appeler incorrectement peut être dangereux.

Voici la page de manuel de la version Perl de Larry Wall livrée avec Ubuntu. Vous lui donnez une expression Perl telle que rename 's/\.sql$/.php/' *.sql

Voici la page de manuel pour le changement de nom fourni avec les anciennes distributions Red Hat et CentOS. L'utilisation est simple substitution de chaîne comme rename .sql .php *.sql

Vous pouvez également utiliser une ligne simple pour traiter chaque fichier un à la fois:

$ for f in *.sql; do mv -i "$f" "${f%%.*}.php"; done
32
Ryan Bright

Il y a rename(1) , qui n'utilise pas de regex, mais peut résoudre votre problème:

rename .sql .php *.sql

Il y a aussi mmv(1) , mais je ne connais pas son fonctionnement.

10
Adam Rosenfield

G'day

Vous pouvez également essayer d'entrer

for i in $(\ls -d *.sql)
do
mv $i $(echo $i | sed -e 's/\.sql$/\.php/')
done

Ou pour le faire utiliser regex changer légèrement

for i in $(\ls -d | egrep -e '.*\.sql')
do
mv $i $(echo $i | sed -e 's/\.sql$/\.php/')
done

pour un peu de plaisir de codage Shell. (-:

5
Rob Wells

En tant que plombier, j'aime les pipes :)

Remarque: cette réponse est détaillée - en tant que débutant, je l’apprécie lorsque quelqu'un qui sait prend le temps de l'expliquer, je paie donc "en avant". Si vous n'êtes pas un débutant, veuillez excuser la longueur et la verbosité.

ls -1 *_201[67][0-9]* | sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \2\/\3; mv \1 \2\/\3\/\1/' | bash

Où:

ls -1 *_201[67][0-9]*

liste tous les fichiers correspondant au modèle, dans ce cas, je recherche des fichiers avec la date dans le nom du fichier sous la forme 'AAAAMMJJ'

sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \2\/\3; mv \1 \2\/\3\/\1/'
#        : | |    |     |                  | |       |                    |:                                 :
#        : |^2....^    ^3..................^^4.......^                    |:                                 :
#        :^1..............................................................^:                                 :
#        /................filename.................pattern................./...mkdir...and....mv...command.../

^ 1: 1er groupe de capture - le nom de fichier complet

^ 2: 2e groupe de capture - la 1ère partie du motif de nom de fichier

^ 3: 3ème groupe de capture - la 2ème partie du nom de fichier - ici, la date sous la forme 'AAAAMMJJ'

^ 4: 4ème groupe de capture - partie de nom de fichier facultative située entre la date et l'extension, et l'extension elle-même

Sooooo .... si j'ai un fichier nommé

CallLog_555123412_20161231-214403.7z

...puis

mkdir -p \2\/\3; mv \1 \2\/\3\/\1

signifie en réalité

# make directory and sub-directory
mkdir -p CallLog_555123412/20161231
# move file from current directory to sub-sub-directory just created
mv CallLog_555123412_20161231-214403.7z CallLog_555123412/20161231/CallLog_555123412_20161231-214403.7z

Notez que la sortie de la commande sed est acheminée vers "bash" pour l'exécuter. Pour voir d’abord les mouvements de fichier proposés SANS les déplacer réellement, commencez par supprimer le '| bash 'à la fin, et essayez comme ça:

ls -1 *_201[67][0-9]* | sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \2\/\3; mv \1 \2\/\3\/\1/'

Cela ne fera aucun changement, mais vous verrez la commande qui sera exécutée SI vous l'exécutez avec '| bash 'tagué à la fin.

Cela est utile car vous pouvez créer les sous-répertoires de votre choix à partir de parties du nom de fichier, ou de tout autre élément ajouté au texte de remplacement dans la commande sed. Notez que sed nécessite cependant beaucoup de caractères d'échappement.

Supports SED Regex:

(...) nécessite un échappement pour le regroupement des captures ->\(... \)

{m, n} nécessite un échappement pour quantifier l'objet précédent ->\{m, n \}

/ nécessite d'échapper dans la chaîne de remplacement ->\/

[...] NE PAS obliger à s'échapper pour les classes de personnage

\ 1 dans la chaîne de remplacement fait référence au 1er groupe capturé, et ainsi de suite ...

AVERTISSEMENT DE SÉCURITÉ: NE JAMAIS PIPE RIEN DE 'BASSER' SI VOUS COMPRENEZ COMPLÈTEMENT LE RÉSULTAT ...

J'espère que cela aidera à éliminer certains blocages :)

2
skeetastax

Installez mmv, puis procédez comme suit:

mmv "*.sql" "#1.php"
1
Gepsens