renomeando arquivos sem o comando ** rename **

5

Eu tenho um diretório de arquivos,

Measurements Panama 2009-03-22 Session1.xml
Measurements Panama 2009-03-22 Session2.xml
Measurements Panama 2009-03-22 Session3.xml
Measurements Panama 2009-03-22 Session4.xml
...
Measurements Panama 2009-03-22 Session10.xml

e desejo remover os espaços em branco e os caracteres - dash. Não quero usar o comando renomear porque não sei perl nem expressões regulares. De outro post, uma recomendação para remover parte de um nome de arquivo era:

for f in *.png; do mv $f ${f#image}; done

isso parece legal. Não consigo descobrir o que o caracter # faz (suponho que remove a string "image" dos nomes dos arquivos?), De qualquer forma - como remover os espaços e traços?

Eu recebo um erro dizendo que os arquivos não são um diretório ao fazer

[jings]s0128943: for f in *.xml; do mv $f ${f//[ -]/};done

mv: target 'MeasurementsPanama20090322Session10.xml' is not a directory

mv: target 'MeasurementsPanama20090322Session1.xml' is not a directory

etc para todos os arquivos.

    
por Vass 19.10.2010 / 17:50

3 respostas

6

Você pode encontrar informações sobre as substituições ${...} na página man do seu shell, por exemplo, bash (1) . O mais comum:

  • ${var#word} remove o prefixo mais curto: o valor da variável var com o prefixo word (se houver) removido;

  • ${var%word} remove o sufixo mais curto: o valor da variável var com o sufixo word removido (se houver).

  • ${var/pattern/replacement} remove a primeira ocorrência do padrão

  • ${var//pattern/replacment} remove todas as ocorrências do padrão

Então, no seu exemplo, ${f#image} se expande para o valor de f (por exemplo, image01.png ) removendo o prefixo image , então ele gera o valor 01.png .

A parte word e replacement nas expansões ${...} são sujeito às mesmas expansões curinga como nomes de arquivos; assim sendo, Se você quiser remover espaços e - , poderá usar ${f//[ -]/} (substitui qualquer ocorrência de caracteres e - por uma string nula.

Todos os detalhes na página man.

    
por 19.10.2010 / 18:00
2

Se você tem o perl rename (por exemplo, porque você está no Debian ou Ubuntu), é a maneira mais simples de esfolar esse gato em particular (como em um gato individual - existem várias ferramentas para renomear em massa, e pesquisar os arquivos deste site e Super User deve encontrar todos os principais.

rename 's/[- ]//g' *.xml

Dito isto, seu script teria funcionado se você tivesse seguido o mais importante princípio de programação de shell: todas as substituições de variáveis devem ser duplas entre aspas . (Por que você precisa desse pouco extra de sintaxe fluff? Porque há casos em que você realmente quer o comportamento não cotado. Mas esses casos são bastante raros.)

for f in *.xml; do mv "$f" "${f//[ -]/}"; done

Com o zsh, você não precisaria escrever um loop: você poderia usar a função zmv conveniente.

autoload zmv
zmv '(*.xml)' '${1//[- ]/}'
    
por 19.10.2010 / 22:14
1

Você também pode usar sed para criar o novo nome. Lá estaria

for i in *.xml; do mv "$i" 'echo "$i" | sed -e "s/[ -]//g"'; done
    
por 19.10.2010 / 18:14