aggiungere ricorsivamente l'estensione del file a tutti i file


106

Ho alcune directory e sottodirectory contenenti file senza estensione di file. Voglio aggiungere .jpga tutti i file contenuti in queste directory. Ho visto script bash per cambiare l'estensione del file ma non solo per aggiungerne uno. Deve anche essere ricorsivo, qualcuno può aiutare per favore?

Risposte:


228

Comando alternativo senza un loop esplicito ( man find):

find . -type f -exec mv '{}' '{}'.jpg \;

Spiegazione: questo trova ricorsivamente tutti i file ( -type f) a partire dalla directory corrente ( .) e applica il comando di spostamento ( mv) a ciascuno di essi. Nota anche le virgolette in giro {}, in modo che i nomi dei file con spazi (e anche i nuovi caratteri ...) siano gestiti correttamente.


7
In particolare, questo funziona meglio se c'è un numero enorme di file nella struttura della directory (facendo sì che bash si arrabbi per la lunghezza dell'elenco di file su cui iterare).
DrAl

@ Al, se ti riferisci a un forciclo che sconvolge bash per iterare su un elenco di file, non è corretto. Il forciclo bash emette iterativamente ogni mvcomando.
nik

Domanda: findimposta prima un elenco di file prima di eseguire l' -execistruzione? Immagino di sì, ma voglio chiarire questo punto prima di codificare loop infiniti.
Boldewyn

2
questo comando troverà anche i file con estensione. È questo che vuole OP?
ghostdog74

1
@ ghostdog74: Dato che ha accettato questa risposta, apparentemente quanto sopra ha funzionato. Altrimenti, come hai detto di seguito, l'aggiunta -not -name "*.*"farà il trucco.
Stephan202

62

questo troverà i file senza estensione e aggiungerà il tuo .jpg

find /path -type f -not -name "*.*" -exec mv "{}" "{}".jpg \;

Questo fornirà sicuramente il risultato desiderato il 99% delle volte. +1
les

9

Questo è un po 'tardi, ma ho pensato di aggiungere che una soluzione migliore (anche se forse meno leggibile) di quelle finora potrebbe essere:

find /path -type f -not -name "*.*" -print0 | xargs -0 rename 's/(.)$/$1.jpg/'

L'utilizzo del find | xargsmodello generalmente si traduce in un'esecuzione più efficiente, poiché non è necessario eseguire il fork di un nuovo processo per ogni file.

Si noti che ciò richiede la versione di rinomina trovata nelle distribuzioni in stile Debian (aka prename), piuttosto che la tradizionale rinomina. Tuttavia, è solo un minuscolo script Perl, quindi sarebbe abbastanza facile usare il comando sopra su qualsiasi sistema.


4

come questo,

for f in $(find . -type f); do mv $f ${f}.jpg; done

Non mi aspetto che tu abbia nomi di file separati da spazi,
se lo fai, i nomi dovranno essere elaborati un po '.

Se vuoi eseguire il comando da qualche altra directory,
puoi sostituire il file find .con find /target/directory.


1
Manca un 'do' e se ci sono spazi nel nome del file, potrebbe essere meglio citare il nome del file: for f in $ (find. -Type f); esegui mv "$ f" "$ {f} .jpg"; fatto
DrAl

e presumibilmente lo eseguirò dall'interno della directory di primo livello?
robjmills

@seengee: sì. Nota che questo comando manca anche il trattino -type.
Stephan202

Sono dovuto andare da qualche parte e ho digitato troppo velocemente ... il problema ora.
nik

1

Per rinominare tutti i file senza estensione in Windows Basic puoi farlo ren * *.jpg Poiché il file non ha estensione, usa solo *, o se vuoi cambiare png in jpg usaren *.png *.jpg


0

rename

non sono sicuro che possa rinominare i file senza estensioni (sono su Windows 7 in questo momento)


1
può, ma rinominerà anche le directory e non c'è modo di dirgli di funzionare in modo ricorsivo nelle sottodirectory (almeno con la versione che ho su Ubuntu).
mirod

Conosco almeno due diversi comandi chiamati rename, uno un programma C incluso in util-linux-ng e uno un programma Perl (dallo stesso Wall) sulle macchine Debian della nostra università. In realtà, nessuno di entrambi fa la ricorsione.
Boldewyn
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.