Como remover ponto e espaço do início dos nomes de arquivos

7

Estou tentando alterar arquivos jpg nomeados com um ponto e um espaço no início e com um ponto ausente antes do final (como este . Startjpg to Start.jpg

O ponto torna os arquivos ocultos de sed e ls -al listam esses arquivos, então estou canalizando ls -al para sed . Já li muitos manuais on-line e sempre recebo esse erro

sed: -e expression #1, char 6: unknown command: '/'

Eu tentei

ls -al | sed -r '/^\./*.*/g'
ls -al | sed -r '/^\.//g'
ls -al | sed -r '/.*/[\.]g'
ls -al | sed 's/^\./\1*./g'

e muitos mais e muitos mais muitos.

também preciso alterar filejpg para file.jpg

    
por user251046 23.07.2014 / 18:17

3 respostas

8

Com a ferramenta Perl rename (que é chamada rename no Debian e amigos incluindo o Ubuntu, pode ser prename em outro lugar):

rename -n 's/(?<!\.)jpg$/.jpg/' *  # -n makes it show you what it'll do,
                                   # but not actually do it. Remove the -n to
                                   # actually rename

Para quebrar esse padrão: o jpg$ significa "termina com 'jpg'". O (?<!\.) significa 'não há um ponto antes desse' jpg '". Isso impede que você altere foo.jpg para foo..jpg , o que seria bobo.

O * é o curinga normal da shell; rename pega uma lista de arquivos para considerar renomear. É claro que você pode fazer /path/to/dir/* , passar uma lista de nomes de arquivos, usar em conjunto com find , etc.

Remover pontos e espaços desde o início também é bastante fácil:

rename -n 's/^[. ]+//' *          # trying -n first is good practice

Isso removerá todos os pontos e espaços no começo. Isso transformará . . . foo em foo .

Normalmente, a expansão% shell * não renderá arquivos que tenham um nome começando com um ponto (arquivos ocultos). Uma opção é usar .* ; Isso também renderá as duas entradas especiais . (diretório atual) e .. (diretório pai). Isso deve ser inofensivo neste caso; o primeiro comando irá ignorá-los (eles não terminam em jpg ); o segundo comando tentará renomeá-los, mas isso deve apenas produzir um erro. Uma alternativa é encontrar:

find -type f -exec rename -n 's/^[. ]+//' '{}' +

-type f limitará a apenas arquivos. Você também pode usar qualquer outra opção do find.

    
por 23.07.2014 / 18:33
4

Embora sed seja uma ferramenta muito útil e versátil, você não a está usando corretamente. É melhor usado para combinar e substituir strings em arquivos de texto; ele não pode renomear diretamente os arquivos no sistema de arquivos.

Esta tarefa é mais adequada para um one-liner bash (supondo que seja seu shell). Para renomear algo como . filejpg para file.jpg , use:

find . -name '. *' -print0 | while read -d $'
while <something is true>; do
    <run some commands>
done
' file; do short_file=${file%jpg}.jpg; mv "$file" "${short_file:4}"; done

Explicação

find é um programa que retorna caminhos para arquivos que correspondem a uma determinada propriedade de arquivo, neste caso, o nome do arquivo. Se tudo o que você queria saber era quais arquivos .jpg estão em subdiretórios do caminho atual, você faria find . -name "*.jpg" . Normalmente isso gera cada arquivo em uma nova linha. O -print0 separa as correspondências com um caractere nulo. Isso permite o tratamento adequado de nomes de arquivos com espaços quando passamos a saída para os próximos comandos.

O caractere | é conhecido como um pipe. Ele diz ao shell para obter a saída do comando à esquerda e passá-lo como entrada para o comando à direita, neste caso, o comando read dentro do loop while .

O comando read é usado para obter a saída de find e atribuí-la a uma variável, file . Normalmente, isso designaria valores a file de cada palavra por vez, mas o -d $'find'$ faz com que as atribuições sejam delimitadas pelo caractere nulo (correspondendo como delimitamos os arquivos em -print0 usando o read flag).

Os loops while fazem com que do atribua iterativamente valores a "file" para cada nome de arquivo correspondente. Os done e short_file=${file%jpg}.jpg fazem parte da sintaxe bash padrão para um loop while:

find . -name '. *' -print0 | while read -d $'
while <something is true>; do
    <run some commands>
done
' file; do short_file=${file%jpg}.jpg; mv "$file" "${short_file:4}"; done

Nesse caso, nosso "executar algum comando" primeiro corrige a extensão do nome do arquivo e o atribui a uma nova variável: . filejpg changes . file.jpg to mv . Em seguida, ele executa . para renomear o arquivo, removendo mv "$file" ${short_file:2} no início do nome do arquivo corrigido pela extensão: %code% .

    
por 23.07.2014 / 18:26
0

Como uma alternativa às outras respostas, você pode usar a ferramenta gráfica GPRename . Ele pode substituir caracteres, truncar nomes de arquivos, etc. A vantagem é que há uma função de visualização interna para verificar os novos nomes de arquivos antes de renomeá-los. Mas como funciona em um diretório por vez, será inconveniente usá-lo com várias pastas em subpastas. Mas para menos de 10 pastas não é um problema.

    
por 24.07.2014 / 04:48