cambia l'intero albero di directory in nomi minuscoli


12

Sto lavorando alla conversione di un sito Web. I file così come erano collegati e serviti dal server web non facevano distinzione tra maiuscole e minuscole. Ma ho creato un dump del sito sul mio sistema Linux e sto scrivendo script per migrare i dati. Il problema è che sto riscontrando problemi di sensibilità tra maiuscole e minuscole tra le stringhe di collegamento nelle pagine e il caso reale nel file system.

Ad esempio, una pagina potrebbe avere un collegamento simile a <a href='/subfolder/PageName.asp'>quello del file effettivo /subfolder/pagename.asp. Allo stesso modo con le immagini - <img src='spacer_sm.gif'>potrebbe essere Spacer_Sm.gif.

Quindi il mio pensiero è quello di cambiare tutte le directory e i nomi dei file nei loro equivalenti minuscoli per il download del sito. Come posso farlo (e potrebbe esserci un modo migliore?)

Anche se ci sono comandi unix che hanno opzioni case insensitve, sto usando php, quindi non tutti i comandi del filesystem hanno opzioni per la distinzione tra maiuscole e minuscole.


2
Vedi una domanda precedente simile . Ho ripubblicato una risposta più semplice qui perché la domanda è un po 'più specifica.
Gilles 'SO- smetti di essere malvagio' il

Risposte:


8

Non so se il tuo unix-flavour abbia un rename. Molti Linux hanno, ed è parte di un pacchetto perl, se si cerca un repository.

find ./ -depth -exec rename -n 'y/[A-Z]/[a-z]/' {} ";"

Versione precedente con

rename -n 

non esegue realmente l'azione, ma stampa solo ciò che sarebbe stato fatto. Ometti il ​​-n per farlo sul serio.


Quale "lingua" o regex è la 'y/[A-Z]/[a-z]/'parte?
user394

Bene, dato che renamefa parte di un perlpacchetto, immagino perl, ma lo schema è usato sedanche in, e forse AWKanche in. Conosco solo bene la sedquiete. Traduco yin translateo map, ma non so da dove provenga il personaggio.
utente sconosciuto

Deve essere perl regex - Gilles nella sua risposta dice che renameè uno script perl.
user394

Sì, e puoi usare perl regexs, per modificare i nomi dei file, che non necessariamente si concludono dalla scrittura in perl, ma che potrebbe essere la domanda più interessante.
utente sconosciuto

9

zsh

zmv -o-i '(**/)(*)' '$1${2:l}'

Spiegazioni: zmvrinomina i file corrispondenti a un modello in base al testo di sostituzione fornito. -o-ipassa l' -iopzione a ciascun mvcomando sotto il cofano (vedi sotto). Nel testo di sostituzione, $1, $2, ecc, sono i successivi gruppi tra parentesi nel modello. **indica tutte le (sotto) * directory, ricorsivamente. Il finale (/)non è un gruppo tra parentesi ma un qualificatore glob che intende abbinare solo le directory. ${2:l}converte $2in minuscolo.

Rinominare il Perl

Qui uso lo script di rinomina Perl /usr/bin/prenamefornito da Debian e Ubuntu (normalmente disponibile renameanche). Con bash ≥4 o zsh:

shopt -s globstar  # only in bash
rename 's!/([^/]*/?)$!\L/$1!' **/*

Con altre conchiglie:

find . -depth -exec rename -n 's!/([^/]*/?)$!\L/$1!' {} +

Portatile

ricorsivamente:

find . -depth -exec sh -c '
    t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
    [ "$t" = "$0" ] || mv -i "$0" "$t"
' {} \;

L'uso di -depthassicura che le directory profondamente annidate vengano elaborate prima dei loro antenati.


1

Non ha funzionato sulla seguente struttura di directory:

JKL/
deF/
ABC/DEf
ABC/gHi
ghi/jkL

Ecco un esempio che funziona:

for i in `find | sort -r | sed '$d'`; do \
   b=${i%/*}; e=${i##*/}; mv $i $b'/'${e,,}; done

Per una spiegazione be vari e:

man bash

Quindi utilizzare la seguente sequenza di tasti: /,,Enterbb


0

La risposta accettata non ha funzionato per me in quanto ha cercato di cambiare tutte le directory contemporaneamente. Ho trovato un'altra soluzione su stackexchange molto simile a quella portatile di Gilles sopra: da Baramin -
/programming/4268591/unix-rename-files-directories-to-uppercase

L'ho copiato qui:

find . -depth | \
while read LONG; do
   SHORT=$( basename "$LONG" | tr '[:lower:]' '[:upper:]' )
   DIR=$( dirname "$LONG" )
   if [ "${LONG}" != "${DIR}/${SHORT}"  ]; then
     mv "${LONG}" "${DIR}/${SHORT}"
   fi
done

A cui ho cambiato il comando tr in ie: sed s / cat / dog / g

Ogni ringraziamento va a Baramin al link sopra

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.