Rinomina in modo ricorsivo i file (cambia estensione) in Linux


21

Come rinominare tutti i file in una directory, ricorsivamente, cambiando un'estensione di file in un'altra, per migliaia di file in migliaia di sottocartelle? Vedo molti comandi che fanno quasi quello che voglio, ma non del tutto.

find . -name "*.andnav" -exec rename .andnav .tile {} \;
syntax error at (eval 1) line 1, near "."

...

rename -nv 's/\.andnav$/\.tile/i' *.andnav
0.png.andnav renamed as 0.png.tile

1
Hai Debian renameo Red Hat rename?
Ignacio Vazquez-Abrams,

@Ignacio: Ubuntu = Debian?
endolith il

Sì, Ubuntu è un derivato Debian.
Ignacio Vazquez-Abrams,

Risposte:


23

Capito

find . -name "*.andnav" -exec rename -v 's/\.andnav$/\.tile/i' {} \;
./0/0.png.andnav renamed as ./0/0.png.tile
./0/1.png.andnav renamed as ./0/1.png.tile
./1/0.png.andnav renamed as ./1/0.png.tile
./1/1.png.andnav renamed as ./1/1.png.tile

ovviamente rimuovi -v quando lo stai effettivamente facendo, altrimenti perderai tempo a visualizzare tutti i file


13

Qualcosa di simile a:

find . -name '*.andnav' -exec sh -c 'mv "$0" "${0%.andnav}.tile"' {} \;

questo ha funzionato meglio per me
Cwd

13

Con zsh:

autoload zmv
zmv -n '(**/)(*).andnav' '$1$2.tile'

Rimuovere il -nper eseguire effettivamente la ridenominazione.


1
Risposta fantastica!
Chris Knadler,

4

Ho trovato questo metodo più semplice e più facile da leggere:

find . -name "*.andnav" | rename "s/\.andnav$/.tile/"

Almeno nelle derivazioni di Ubuntu la ridenominazione prende un elenco di file da STDIN se nessuno si trova sulla riga di comando. E questo può essere testato facilmente con:

find . -name "*.andnav" | rename -vn "s/\.andnav$/.tile/"

fino a quando non hai capito bene.


1

Rinominare file e directory con find -execdir | rename

Se hai intenzione di rinominare file e directory non semplicemente con un suffisso, allora questo è un buon modello:

PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
  find . -depth -execdir rename 's/findme/replaceme/' '{}' \;

La fantastica -execdiropzione fa un cdnella directory prima di eseguire il renamecomando, a differenza -exec.

-depth assicurarsi che la ridenominazione avvenga prima sui bambini e poi sui genitori, per evitare potenziali problemi con le directory dei genitori mancanti.

-execdir è necessario perché la ridenominazione non viene riprodotta correttamente con percorsi di input senza nome di base, ad esempio i seguenti errori:

rename 's/findme/replaceme/g' acc/acc

L' PATHhacking è necessario perché -execdirha uno svantaggio molto fastidioso: findè estremamente supponente e si rifiuta di fare qualsiasi cosa -execdirse ci sono percorsi relativi nella PATHvariabile di ambiente, ad esempio ./node_modules/.bin, non riuscendo con:

find: il percorso relativo './node_modules/.bin' è incluso nella variabile d'ambiente PATH, che non è sicura in combinazione con l'azione -execdir di find. Rimuovi quella voce da $ PATH

Vedi anche: https://askubuntu.com/questions/621132/why-using-the-execdir-action-is-insecure-for-directory-which-is-in-the-path/1109378#1109378

-execdirè un'estensione di ricerca GNU a POSIX . renameè basato su Perl e proviene dal renamepacchetto. Testato su Ubuntu 18.10.

Rinomina soluzione alternativa lookahead

Se i tuoi percorsi di input non provengono findo se hai abbastanza del fastidio relativo del percorso, possiamo usare alcuni lookahead Perl per rinominare in modo sicuro le directory come in:

git ls-files | sort -r | xargs rename 's/findme(?!.*\/)\/?$/replaceme/g' '{}'

Non ho trovato un analogo conveniente per -execdircon xargs: Xargs: cambia la directory di lavoro nel percorso del file prima di eseguire?

Il sort -rè tenuto a garantire che i file vengono dopo rispettive directory, dal momento che i percorsi più lunghi vengono dopo quelle più corte con lo stesso prefisso.

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.