Removendo o apóstrofo de todos os nomes de arquivos

6

Eu tentei remover o apóstrofo dos nomes de todos os arquivos no diretório.

for i in *; do mv $i 'echo $i | tr -d "'"'; done

Depois de executar este comando, nada é renomeado.

Você sabe o que há de errado aqui?

    
por xralf 06.05.2012 / 12:18

3 respostas

8

Você poderia tentar algo assim ( bash ):

shopt -s nullglob
for i in *\'* ; do mv -v "$i" "${i/\'/}" ; done

Isso usa a substituição da string do shell. Você provavelmente não deseja glob arquivos que não têm ' neles, pois o mv falharia. Sem a opção nullglob , o próprio padrão glob seria passado para mv se não houvesse arquivos correspondentes.

    
por 06.05.2012 / 13:05
6

Sempre coloque aspas duplas em torno das substituições de variáveis $foo e substituições de comandos $(foo) (a menos que você saiba por que precisa deixá-las de fora e por que não há problema em fazê-lo).

for i in *; do mv "$i" "$(echo "$i" | tr -d "'")"; done

Isso funcionará principalmente, com algumas restrições:

  • Você receberá um mau comportamento ou erros se um nome de arquivo começar com - , porque mv o interpretará como uma opção.
  • Isso não afeta os arquivos cujo nome começa com . .
  • Com algumas configurações, isso gerará barras invertidas no comando echo .
  • As novas linhas no final do nome são perdidas.

No ksh93, bash e zsh, você pode escrever isso com menos problemas usando a construção ${VARIABLE//PATTERN/REPLACEMENT} . A adição de -- a mv cuida dos nomes de arquivos que começam com - . Se você tiver nomes de arquivos que comecem com . , adicione .* ou .[^.]* ..?* após * conforme necessário.

for i in *; do mv -- "$i" "${i//\'/}"; done

No zsh, você pode usar zmv :

zmv '(*)' "\${1//\'/}"

No Debian, Ubuntu e outros derivados, você pode usar o rename Script Perl.

rename "s/'//g" *
    
por 07.05.2012 / 03:59
3

Eu assumo que seu problema é que o arquivo também possui espaços em seu nome. Não consigo reproduzir seu erro sem ele.

$ touch "file" "user's file"
$ for i in *; do mv $i 'echo $i | tr -d "'"'; done
mv: 'file1' and 'file1' are the same file
mv: target 'file' is not a directory

Portanto, o motivo da falha é a segunda mensagem: target 'file' is not a directory .

Quando seu loop for vê um arquivo com um espaço, ele executa isto:

mv user's file users file

Então, você acha que está especificando três arquivos ( user's , file e users ) e um diretório para mover esses arquivos para ( file ).

A citação adequada de ambos deve resolver seu problema imediato

$ for i in ./*; do mv "$i" "$(echo "$i" | tr -d "'")"; done
    
por 06.05.2012 / 16:50