Rinominare i file in batch


151

Ho una directory piena di immagini:

image0001.png
image0002.png
image0003.png
...

E vorrei un one-liner per rinominarli (diciamo).

0001.png
0002.png
0003.png
...

Come faccio a fare questo?


8
Questa è una delle principali domande frequenti sulla riga di comando di Unix e non la trovo già su questo sito, quindi dovremmo creare questo Wiki della community?
Gilles,

5
Non vedo perché. È una domanda specifica con una risposta verificabile.
Internet man,

3
Se stai eseguendo X non è molto più facile rispetto thunar -B *.pngallo strumento gui di rinominazione in blocco di thunar.
dotjoe,

@dotjoe Grazie, Thunar è davvero interessante.
Volker Siegel,

Risposte:


106

Se stai usando Bash o un'altra shell compatibile con POSIX:

for f in *.png; do
    mv -- "$f" "${f#image}"
done

2
Questo è uno dei metodi di sostituzione dei parametri mostrati nella guida di script di Bash Advanced Mendel Coopers tldp.org/LDP/abs/html
W_Whalley

2
@W_Whalley Consiglio vivamente di evitare quella guida, a favore della Wooledge Bash Guide .
Wildcard il

@Wildcard: quali sono i motivi per cui hai raccomandato di evitare la guida ABS?
Christian Severin,

@ChristianSeverin promozione di cattive pratiche e codice completamente rotto. Controlla i collegamenti sulla pagina del mio profilo.
Wildcard l'

Se non sai come adattare questo esempio a diversi modelli di file, potresti dare un'occhiata alla sezione di espansione dei parametri della guida sopra menzionata.
lex82,

108

Su Debian e derivati, Perl renamefunziona in modo simile a sedquesto:

  rename -v 's/image//' *.png

C'è anche il renameda util-linuxche funziona in questo modo, invece:

  rename image '' *.png

6
dovresti davvero spiegare che questo è un programma perl che potrebbe essere necessario installare e che richiede espressioni regolari come argomento.

Ah, non ne ero a conoscenza. Darò credito alla risposta canonica, quando la identificherò :)
Internet man,

5
Questo renameprogramma proveniva da una distribuzione di esempi Perl. Debian e Ubuntu lo spediscono come /usr/bin/rename. Altre varianti Unix potrebbero non fornirlo o potrebbero fornire un completamente diverso /usr/bin/rename.
Gilles,

1
Alcune versioni di renameprendere una da al criterio di sostituzione:rename [options] <expression> <replacement> <file>...
fonde

1
Se si utilizza un sistema basato su Debian, quindi sudo apt-get install rename, è possibile utilizzare il comando rename. È sed per i nomi di file.
ctrl-alt-delor,

41

ZMV

La shell zsh ha un potente comando di rinomina batch chiamato zmv.

Per prima cosa devi abilitare il zmvcomando come segue (questo può andare nel tuo ~/.zshrc).

autoload zmv

La sintassi di base è zmv PATTERN REPLACEMENT. Il modello è un'espressione glob shell. Parti del motivo possono essere racchiuse tra parentesi. Il testo sostitutivo può contenere $1, $2ecc. Per fare riferimento all'ennesimo gruppo tra parentesi nel modello. Per esempio:

zmv 'image(*.png)' '$1'

Si può anche chiedere zsh per definire automaticamente $1, $2e così via per abbinare i caratteri jolly nel modello:

zmv -w 'image*.png' '$1.png'

4
sweeeeeeeeeeeeeeeeeet. ancora un altro motivo per cui dovrei imparare zsh.
ixtmixilix,

1
@ixtmixilix cosa imparare? Basta iniziare a usarlo e forse aggiungere prezto ( github.com/sorin-ionescu/prezto ) per un po 'di più.
Gerry,

Davvero bello, come indicato nell'uomo di zmv, questo può essere ulteriormente semplificato aggiungendo alias mmv = 'noglob zmv -W' a: mmv * .c.orig orig / *. C
Bretsko

Per zmvabilitare prezto è necessario rimuovere il commento dalla riga nel tuo ~ / .zpreztorc dopo # Set the Zsh functions to load (man zshcontrib).aver datozstyle ':prezto:load' zfunction 'zargs' 'zmv'

33

Normalmente uso l' utilità mmv ( man page ) piacevole e semplice per questo esempio:

$ mmv "image*.png" "#1.png"

eseguirà il tuo compito.

Il #1modello di destinazione verrà sostituito con qualsiasi cosa corrisponda al carattere jolly nel modello di origine. Questo funziona anche con diversi caratteri jolly e può essere utilizzato ad esempio per modificare l'ordine delle parti dei nomi dei file. Puoi anche fare facilmente cose più complicate come convertire lettere minuscole in lettere maiuscole.

Assicurati di proteggere i motivi dalla shell citando.


Grazie per aver segnalato questa utility. L'ho trovato nei repository Debian, Ubuntu e Cygwin. Ho avuto problemi con la pagina man, ma ho trovato alcune pagine web e questa domanda Stack Overflow che ti ha aiutato a spiegare come la stavi usando. stackoverflow.com/questions/417916/how-to-do-a-mass-rename
W_Whalley

Grazie, ho aggiunto alcune informazioni in più alla risposta per renderlo più chiaro.
Marcel Stimberg,

3
Non posso votarlo abbastanza! È così semplice e amichevole. Disponibile per OS X in homebrew.
Greg Dubicki,

9

POSIX sh per loop

Usa sed per rinominare

for i in image*jpg
do 
  mv -v "$i" "$(echo "$i" | sed -e 's/^\.\/image//' - )"
done

6

Mi piace Perl così:

perl -nlE '$old=$_; s/image//; qx(mv $old $_)'

Puoi anche usare lo stesso modello per altre attività come copiare i file in un'altra directory:

perl -nlE '$old=$_; s(image)(/path/to/new/dir/); qx(mv $old $_)'

2
O (più sicuro!):rename($old,$_)
reinierpost il

5

voto a maggioranza qualificata

Il comando qmvda renameutilsapre un editor che mostra un elenco di nomi di file con due colonne, separate da una scheda. Ogni riga mostra uno dei nomi dei file, lo stesso in entrambe le colonne. La colonna di destra rappresenta i nuovi nomi dei file.
Per apportare modifiche, modifica i nomi sul lato destro. In questo esempio, :%s/...o la modalità blocco visivo sono utili.

Nomi dei file nel tuo editor

$ qmv *.png

Nell'editor:

image0001.png           image0001.png
image0002.png           image0002.png
image0003.png           image0003.png         
~                                             
~                                             
~                                             
~                                             
"/tmp/user/1000/qmvxWyVMs" 3L, 93C

Modifica i nomi nella colonna di destra:
(Rimozione del imageprefisso da tutte le righe usando la modalità blocco visivo)

image0001.png           0001.png
image0002.png           0002.png
image0003.png           0003.png         
~                                             
~                                             
~                                             
~                                             
:wq

Registro di ridenominazione:

image0001.png -> 0001.png
image0002.png -> 0002.png
image0003.png -> 0003.png

(es Ubuntu: apt-get install renameutils)


3

ricorsivo

facilità di selezione selezionando i file image * png e non presuppone la necessità di occuparsi di newline nei nomi dei file

find . -name "image*.png" | while read f; do mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; done

Sicuro, in grado di gestire spazi, nuove linee, barre rovesciate e qualsiasi altra cosa :

find . -name "image*.png" | while IFS= read -r f; do 
   mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; 
done

1

POSIX sh utilizza un ciclo while

Lettura dei nomi dal findcomando.

find . -maxdepth 1 -type f -name 'image*png' | while IFS= read -r f; do
  mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"
done

Lettura di nomi da un file

while IFS= read -r f; do mv -v "$f" "$(echo "$f"|sed -e 's/^\.\/image//' - )"; done < flist


1

Per Windows e Linux , questo script Perl farà; in questo caso:

$ rnm -l 's/^image//' '*.png'

Lo script potrebbe essere eseguito in modo ricorsivo sotto directory e persino anteporre un conteggio a tutti:

$ rnm -r 's/^/$counter./' '/\.png$/'

Anche i caratteri UTF-8 sono trattati correttamente, sia in Windows che in Linux.


0

Puoi usare questo strumento: rnm ( pagina web )

Per il tuo caso il comando sarebbe:

rnm -rs '/^image//' *.png

Puoi trovare altri esempi / documenti qui .


0

Prova brename ( https://github.com/shenwei356/brename ), un pratico strumento da riga di comando multipiattaforma per rinominare in batch file / directory in modo sicuro tramite espressione regolare (che supporta Windows, Linux e OS X).

@patrickDurusau ha detto:

Linux ha una varietà di opzioni per rinominare i file batch, ma non ho visto alcun difetto nel nome del marchio che mi è saltato fuori.

Caratteristiche:

  • Multipiattaforma . Supporto per Windows, Mac OS X e Linux.
  • Sicuro . Con il controllo dei potenziali conflitti ed errori .
  • Filtro file . Supporta l'inclusione e l'esclusione dei file tramite l'espressione regolare. Non è necessario eseguire comandi come find ./ -name "*.html" -exec CMD.
  • Rinominare l'invio con il valore corrispondente tramite il file valore-chiave .
  • Rinomina tramite numero intero crescente .
  • Rinominare in modo ricorsivo sia i file che le directory .
  • Sostenere la corsa a secco .
  • Uscita colorata .

Comando:

$ brename -f .png -p image
[INFO] checking: [ ok ] 'image0001.png' -> '0001.png'
[INFO] checking: [ ok ] 'image0002.png' -> '0002.png'
[INFO] checking: [ ok ] 'image0003.png' -> '0003.png'
[INFO] 3 path(s) to be renamed
[INFO] renamed: 'image0001.png' -> '0001.png'
[INFO] renamed: 'image0002.png' -> '0002.png'
[INFO] renamed: 'image0003.png' -> '0003.png'
[INFO] 3 path(s) renamed

-5

ls * png | mentre leggi -rf; do f2 = "` echo $ f | sed -e's / image // '`"; mv $ f $ f2; fatto


Qualcosa non va: "mv: operando file di destinazione mancante dopo 'image0001.png'"
Internet man

3
Ci sono molti problemi con il tuo codice. L'analisi dell'output di lsrichiede solo problemi. readdovrebbe essere read -r. tutte le sostituzioni variabili devono essere racchiuse tra virgolette doppie.
Gilles,

Potresti scrivere questo in modo più efficace come for f in *png; do f2="$(echo "$f" | sed -e 's/image//')"; mv "$f" "$f2"; done. L'analisi lsnon è né necessaria né una buona idea .
Kojiro,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.