Como eu renomearia muitos arquivos usando a linha de comando?

1

Eu tenho um problema que não consigo resolver: preciso renomear um grande despejo de arquivos usando padrões. Eu tentei usar isso , mas eu sempre recebo um erro.

Eu tenho uma pasta, dentro de um lote de arquivos. Correndo ls -1 | wc -l , retorna que eu tenho 160000 arquivos dentro. O problema é que eu desejo mover esses arquivos para um sistema Windows, mas a maioria deles tem caracteres como : e ? neles, o que torna o arquivo inacessível nos sistemas baseados no Windows.

(Como um método "não resolva, mas lide com" , tentei inicializar um LiveCD no sistema Windows e mover os arquivos usando o SO ao vivo. Sob esse Ubuntu, os arquivos eram legíveis e gravável na partição NTFS montada, mas quando eu reiniciei no Windows, ele mostrou que o arquivo está lá, mas o Windows não conseguiu acessá-lo de qualquer maneira: renomeie, apague ou abra.)

Eu tentei executar rename 's/\:/_' * dentro da pasta, mas recebi um erro Argument list too long . Algumas pesquisas revelaram que isso acontece porque tenho muitos arquivos, e então cheguei aqui . O problema é que eu não sei como alterar o comando para atender às minhas necessidades, pois sempre acabo tendo vários erros como

  • Experimentando find -name '*:*' | xargs rename : _ , ele fornece xargs: cotação única sem correspondência; por padrão, aspas são especiais para xargs a menos que você use a opção -0 [\ n] erro de sintaxe na (eval 1) linha 1, próximo a ":" [\ n] xargs: rename: encerrado com status 255; abortando
  • A adição do -0 após xargs transforma a mensagem de erro em xargs: linha de argumento por muito tempo

Esses arquivos são arquivos gerados por vários scripts PHP. A melhor solução seria ter a chance de renomeá-los antes eles são movidos para o Windows, mas se não há como fazer isso, podemos ter uma maneira de renomear os arquivos enquanto eles são movidos para o Windows. Eu uso samba e proftpd para mover os arquivos.

Infelizmente, os softwares gráficos estão fora de questão, já que o servidor que contém os arquivos é o que é, um servidor, com apenas uma interface de linha de comando.

    
por Whisperity 19.06.2012 / 12:43

2 respostas

2

O uso de -exec do find deve funcionar, embora seja recursivo por meio de subdiretórios, o que, por sua vez, falhará se algum dos subdiretórios contiver : ou ? .

find . -name "*[:?]*" -exec rename 'y/:?/__/' {} +

O erro argument list too long que você obtém porque o * é expandido para todos os 160k arquivos no diretório, o que excede o tamanho máximo do argumento em seu sistema.

$ getconf ARG_MAX
2097152

160k nomes de arquivos podem facilmente exceder 2 MiB. Você pode trabalhar além disso renomeando um arquivo de cada vez

for file in ./*[:?]*; do 
    mv "$file" "${file//[:?]/_}"
done

ou preencha uma matriz e processe-os em blocos. O tamanho da parte do bloco depende do comprimento médio dos nomes de arquivos e do valor de ARG_MAX; ou apenas definir um valor baixo o suficiente para ser seguro, por ex. 1000:

files=( ./*[:?]* ) n=${#files[@]}
size=1000
for (( i=0; i<n; i+=size )); do
    rename 'y/:?/__/' "${files[@]:i:size}"
done

Veja também BashFAQ 30 .

    
por geirha 19.06.2012 / 13:17
2

Eu uso isso para renomeação em massa: vidir . Usa mais ou menos a mesma sintaxe que us vi faz!

apt-get install moreutils

Vá para o diretório com os arquivos 160k

cd dir

Iniciar vidir

vidir

Em seguida, substitua todos: no nome do arquivo por, por exemplo,

: % s/:/-/g

Faça o mesmo com outros personagens estranhos como?

: % s/?/-/g

Agora salve os arquivos com: w

vidir permite editar o conteúdo de um diretório em um editor de texto.

link

    
por koni_raid 19.06.2012 / 12:54