renomeia (1) um conjunto de arquivos além do diretório atual

3

O comando rename no Ubuntu 12.04 (manpage diz que é parte do perl v5.14.2 2012-03-23) funciona bem em um único diretório, mas eu quero usá-lo em subdiretórios também (ou, mais geralmente, em uma lista de arquivos que é a saída de outro comando, por meio de backquotes). Por exemplo, eu esperaria

rename "s/ /-/g"  'find .'

para alterar todos os espaços para traços em todos os nomes de arquivos abaixo do diretório atual. Mas esse comando não faz nada.

( Editar : alterou rename -n para rename . Essa opção é boa para experimentar com segurança, mas apenas uma distração aqui.)

As backquotes não têm culpa, porque a substituição de find . por, por exemplo, echo */* funciona.

Primeiro, fazendo find . > foo e, em seguida, substituindo find . por cat foo , não faz nada.

Mesmo reduzindo a lista de arquivos em uma linha, substituindo find . por find . | tr -d '\n' , não faz nada.

Qual elemento está com defeito?

    
por Camille Goudeseune 07.10.2014 / 00:01

1 resposta

2

Isso não funcionará:

rename 's/ /-/g'  'find .'

Depois de executar o comando find, o shell faz a divisão de palavras nos resultados. Conseqüentemente, nenhum nome de arquivo com espaços sobrevive ao tato: ele é dividido em partes.

Você pode evitar isso usando:

rename 's/ /-/g'  */*

Nesta forma de comando, o shell não faz a divisão de palavras e seu rename será bem-sucedido. Este formulário funciona mesmo para nomes de arquivos com espaços, tabulações ou qualquer outro caractere difícil.

Como alternativa, use -exec :

do find
find . -name '* *' -exec rename 's/ /-/g' {} +

Este formulário funcionará com nomes de arquivos com espaços, tabulações ou quaisquer outros caracteres difíceis.

Demonstração

Para ver o que está errado, vamos criar um arquivo com espaços

$ touch "a b c"
$ find .
.
./a b c

Para esclarecer o que acontece, vamos criar uma função para colocar cada argumento que ele vê dentro de aspas duplas e exibi-lo:

$ display() { printf '"%s"\n' "$@"; }

Agora, podemos usar display para ver o que acontece quando executamos find . :

$ display 'find .'
"."
"./a"
"b"
"c"

Isso mostra a divisão de palavras em ação. O nome do arquivo a b c foi dividido em três palavras separadas.

    
por 07.10.2014 / 00:20