Come sostituire un carattere con un altro in tutti i nomi di file delle directory attuali?


41

Come rinominare tutti i file / sottocartelle nella cartella corrente?

Diciamo, ho molti file e sottodadi che sono con spazi e voglio sostituire tutti gli spazi con un carattere di sottolineatura.

File 1
File 2
File 3
Dir 1
Dir 3

dovrebbe essere rinominato in

File_1
File_2
File_3
Dir_1
Dir_3

Risposte:


36

Se hai bisogno di rinominare i file anche nelle sottodirectory e il tuo findsupporta il -execdirpredicato, allora puoi farlo

find /search/path -depth -name '* *' \
    -execdir bash -c 'mv -- "$1" "${1// /_}"' bash {} \;

Grazie a @glenn jackman per aver suggerito l' -depthopzione per finde per farmi pensare.

Si noti che su alcuni sistemi (inclusi quelli GNU / Linux), findpotrebbe non riuscire a trovare file il cui nome contiene spazi e anche sequenze di byte che non formano caratteri validi (tipici con file multimediali con nomi con caratteri non ASCII codificati in un set di caratteri diverso dalle impostazioni locali). L'impostazione della locale su C(come in LC_ALL=C find...) risolverà il problema.


Dovresti usare find -maxdepth 1per fare esattamente ciò che l'OP ha chiesto di operare sulla cartella corrente.
Caleb,

1
Usa l' -depthopzione find e puoi sbarazzarti di sort.
Glenn Jackman,

@glenn jackman: grazie, ora capisco che la mia soluzione era sbagliata.
enzotib,

2
Cambia -name '* *'in -name '*_*'e cambia "${1// /_}"in"${1//_/.}"
enzotib il

1
@kroiz: si chiama "Sostituzione del modello". Puoi trovarlo nella bashpagina man di.
enzotib

34

In qualsiasi shell, è possibile eseguire il ciclo sui file il cui nome contiene uno spazio. Sostituire gli spazi con caratteri di sottolineatura è facile in bash, ksh e zsh con il ${VARIABLE//PATTERN/REPLACEMENT}costrutto.

for x in *" "*; do
  mv -- "$x" "${x// /_}"
done

Su Debian, Ubuntu e derivati, puoi usare il Perl rename(altre distribuzioni hanno un programma diverso come rename, e quel programma non è utile qui).

rename 's/ /_/g' *

Una soluzione zsh obbligatoria:

autoload zmv
zmv '(*)' '${1// /_}'

Una soluzione POSIX obbligatoria:

for x in *" "*; do
  y=$(printf %sa "$x" | tr " " "_")
  mv -- "$x" "${y%a}"
done

Cosa significa 'g' alla fine del comando "rinomina"? Non l'ho visto nel manuale.
JulianLai,

Come rinominare solo la directory? Non voglio cambiare il nome del file.
JulianLai,

@JulianLai s/…/…/gsignifica sostituire tutte le occorrenze. Non è molto ben spiegato nel manuale . Se vuoi rinominare le directory, ci sono modi, per favore cercalo (penso di averlo già visto prima) e se non riesci a trovarlo fai una nuova domanda.
Gilles 'SO- smetti di essere malvagio' il

grande ... questo mi ha aiutato a cambiare titolo tutto _MG_blah.JPGa IMG_blah.JPG.
Abinash Dash,

13

È possibile utilizzare renameper questo (qui assumendo quello di util-linux, non perlquello):

cd /path/to/dir
rename ' ' _ *\ *

Questo troverà tutti gli spazi di file e directory nel nome e sostituirà lo spazio con un carattere di sottolineatura. Poiché utilizza la corrispondenza dei file glob, è necessario essere nella directory giusta per iniziare.

Se si desidera eseguire corrispondenze ricorsive, è possibile, ma potrebbe essere necessario eseguire renameun paio di volte per catturare tutti gli elementi nelle directory che sono stati rinominati:

cd /path/to/dir
shopt -s globstar
rename ' ' _ **/*\ *
!!; !!

2
" renameRinominerà i file specificati sostituendo la prima occorrenza di da nel loro nome con a ." Quindi questo funzionerà solo per i file con un singolo spazio nel loro nome. (Potresti chiamare renamein un ciclo, ma non è davvero lo strumento giusto qui.)
Gilles 'SO- smetti di essere malvagio'


1

Su Debian / Ubuntu, basandosi sulle risposte di Caleb e Gilles, questo è ciò che ha funzionato per me nel rinominare i file in modo ricorsivo:

cd /path/to/dir
shopt -s globstar
rename 's/ /_/g' **

Nota: per visualizzare l'anteprima dei file da rinominare e come, utilizzare l' -nopzione con rename:

rename -n 's/ /_/g' **

Un'altra nota: l'impostazione globstarfa **corrispondere i file in tutte le sottodirectory, quindi se si desidera solo la directory corrente, non impostare globstar o usare *invece di** .

Un'altra nota: il renamecomando deve essere eseguito più di una volta per i file con più occorrenze del termine di ricerca.


Funziona solo se le directory non contengono spazi. (una ridenominazione di a b/c dper a_b/c_dnon avrebbe funzionato, avresti bisogno prima di rinominare a b/c da a b/c_d, e poi a ba a_b).
Stéphane Chazelas,

@Stephane: significa eseguire lo stesso renamecomando due volte?
Markus Pscheidt,

Bene, più piace quante volte ci sono livelli nidificati di directory con spazi. Idealmente, si desidera prima attraversare la profondità della directory e convertire solo il nome di base del file come nella soluzione accettata. Si noti inoltre che bash's **esclude dotfile e attraversa i collegamenti simbolici.
Stéphane Chazelas,

0

Se non sei un flash alle espressioni regolari (non lo sono!) E puoi eseguire applicazioni progettate per kde (o usi kde - k desktop o hai le librerie installate), allora krename è una grande utility grafica che ti permette di vedere prima e dopo prima di impegnarti nelle modifiche. Ha una serie di semplici trasformazioni come opzioni e supporta anche espressioni regolari. Puoi anche combinare diverse trasformazioni sequenziali in una rinomina in modo da non dover progettare una singola trasformazione complessa che fa tutto in una volta. Ha anche un'opzione per continuare a rinominare gli stessi file dopo che è stata applicata una ridenominazione.

Non lo uso così spesso, ma quando lo faccio, fa davvero il lavoro rapidamente e facilmente. È davvero utile quando si rinomina vari file multimediali scaricati in modo da poterli gestire in modo uniforme sul proprio sistema. Aiuta a scaricare il manuale di krename separatamente in modo da poter fare riferimento ad esso durante l'utilizzo del programma.

http://www.krename.net/

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.