altera a árvore de diretórios inteira para nomes de minúsculas

11

Estou trabalhando em uma conversão de website. Os arquivos, como eram vinculados e servidos pelo servidor da Web, não faziam distinção entre maiúsculas e minúsculas. Mas, eu fiz um despejo do site no meu sistema linux e estou escrevendo scripts para migrar dados. O problema é que estou correndo em problemas de diferenciação de maiúsculas e minúsculas entre cadeias de link nas páginas e o caso de palavra real no sistema de arquivos.

Por exemplo, uma página pode ter um link como <a href='/subfolder/PageName.asp'> , enquanto o arquivo real é /subfolder/pagename.asp . Da mesma forma com imagens - <img src='spacer_sm.gif'> pode ser Spacer_Sm.gif .

Então, meu pensamento é alterar todos os diretórios e nomes de arquivos para seus equivalentes em minúsculas para o download do site. Como faço isso (e pode haver uma maneira melhor?)

Mesmo se houver comandos unix que possuam chaves com diferenciação de maiúsculas e minúsculas, estou usando php, portanto nem todos os comandos do sistema de arquivos possuem opções para diferenciação de maiúsculas e minúsculas.

    
por user394 07.09.2011 / 00:16

4 respostas

7

Não sei se o seu sabor unix tem um rename . Muitos Linuxes têm, e fazem parte de um pacote perl, se você procurar por um repositório.

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

Acima da versão com

rename -n 

não realiza realmente a ação, mas apenas imprime o que seria feito. Você omite o -n para fazer isso de verdade.

    
por 07.09.2011 / 02:36
7

Zsh

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

Explicações: zmv renomeia arquivos que correspondem a um padrão de acordo com o texto de substituição fornecido. -o-i passa a opção -i para cada comando mv sob o capô (veja abaixo). No texto de substituição, $1 , $2 , etc, são os sucessivos grupos entre parênteses no padrão. ** significa todos os diretórios (sub) *, recursivamente. O% final (/) não é um grupo entre parênteses, mas um qualificador glob que significa corresponder apenas aos diretórios. ${2:l} converte $2 em minúsculas.

Perl renomear

Aqui eu uso o script de renomeação Perl que o Debian e o Ubuntu enviam como /usr/bin/prename (normalmente disponível como rename também). Com bash ≥4 ou zsh:

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

Com outros shells:

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

Portátil

Recursivamente:

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

O uso de -depth garante que diretórios profundamente aninhados sejam processados antes de seus ancestrais.

    
por 07.09.2011 / 02:28
1

Não funcionou na seguinte estrutura de diretórios:

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

Veja um exemplo que funciona:

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

Para uma explicação sobre b e e vars:

man bash

Em seguida, use a seguinte seqüência de teclas: / , , Insira b b

    
por 11.12.2013 / 14:51
0

A resposta aceita não funcionou para mim, uma vez que tentou alterar todos os diretórios de uma só vez. Eu encontrei uma outra solução no stackexchange muito semelhante ao portátil de Gilles acima: de Baramin -
link

Eu copiei aqui:

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

Para o qual eu mudei o comando tr para, por exemplo: seds / cat / dog / g

Qualquer agradecimento vai para Baramin no link acima.i.e.

    
por 11.12.2013 / 11:25