remove os primeiros caracteres se o seu “0” de todos os arquivos

1

eu tenho poucas pastas:

1
2
3
4
5

então em cada pasta eu tenho arquivos como

00123.mp3
00133.mp3
00150.mp3

então eu quero remover todos 0 se eles estiverem no início do nome do arquivo

eu tentei isso

for file in *; do echo mv "$file" "${file//[ ()@0]/}"; done

mas remove todos 0 no início e no nome do arquivo (preciso apenas no início) também isso não está funcionando no subdiretório

    
por arlind 07.02.2018 / 21:33

3 respostas

2

Se você estiver usando o bash, esse script fará o que você pede:

#!/bin/bash
shopt -s extglob
while IFS= read -d '' f ; do
    file=${f##*/}
    dir="${f%/*}/"
    echo \
    mv "$dir$file" "$dir${file##+(0)}"
done < <(find . -type f -name '0*.mp3' -print0)

comente a linha echo \ para realmente executar o (s) comando (s) mv quando você concordar com a lista de arquivos a serem movidos.

Ou esta versão sh para portabilidade:

#!/bin/sh

find . -type f -name '0*.mp3' -print |
while IFS= read f; do
    file=${f##*/}
    dir="${f%/*}/"
    f2=$file; until [ "$f2" = "${f2#0}" ]; do f2=${f2#0}; done
    echo \
    mv "$f" "$dir${f2}"
done
    
por 08.02.2018 / 00:31
2

Como sua pergunta é marcada como Linux, você pode usar o comando rename ou prename (observe que prename não está obsoleto, mas ainda funciona). Em ambos os casos, eles são scripts perl para renomeação baseada em padrões.

Com a correspondência de grupo e usando *.mp3 glob para passar apenas .mp3 arquivos, você pode fazer isso:

$ prename  -nv 's/(^0*)(.*).mp3/$2.mp3/' *.mp3
Deprecated program in use: rename as shipped with the Debian perl package will be removed after the release of stretch. Please install the separate 'rename' package which will provide the same command.
000004500.mp3 renamed as 4500.mp3
00123.mp3 renamed as 123.mp3
00133.mp3 renamed as 133.mp3
00150.mp3 renamed as 150.mp3

Observe que -n e -v são para saída seca e detalhada; testando apenas. Remova -n para que a renomeação real entre em vigor.

Caso você esteja confuso sobre rename vs prename , leia a resposta correspondente esclarece a confusão, mas ... Eu recomendaria que você não se incomodasse com isso. Muito complicado :) O ponto é que, em qualquer caso, funciona como mostrado, a menos que você esteja usando ksh shell.

A maneira recursiva de renomear arquivos em subpastas seria via find , no entanto, isso requer um pouco de acrobacia com padrão de substituição para manipular itens anteriores no caminho do arquivo, conforme fornecido por find .

find ./testdir/ -type f -name "*.mp3" -exec  prename  -nv 's/(.*)(\/0*)(.*).mp3/$1\/$3.mp3/' {} \;

O comando acima foi executado da seguinte forma em um caso de teste:

$ find ./testdir/ -type f -name "*.mp3" -exec  prename  -nv 's/(.*)(\/0*)(.*).mp3/$1\/$3.mp3/' {} \;  2>/dev/null
./testdir/000004500.mp3 renamed as ./testdir/4500.mp3
./testdir/00150.mp3 renamed as ./testdir/150.mp3
./testdir/00133.mp3 renamed as ./testdir/133.mp3
./testdir/00123.mp3 renamed as ./testdir/123.mp3

Melhoria menor poderia ser especificar \d , a classe de dígitos:

find ./testdir/ -type f -name "*.mp3" -exec  prename  -nv 's/\/0*(\d*\.mp3)/\/$1/' {} \;

Stéphane Chazelas mencionou na possibilidade de comentários onde /0/1.mp3 poderia ser acidentalmente renomeado para .//1.mp3 . Eu tomei casos de teste de casal; ./testdir/0/000987.mp3 renamed as ./testdir/0/987.mp3 e ./testdir/007/00123.mp3 renamed as ./testdir/007/123.mp3 foram os resultados. Eu acho que a combinação gananciosa de 0* faz o truque. Ele também sugeriu nos comentários adicionando [^/] na correspondência de padrões de nome de arquivo. Essa é uma boa idéia, já que nomes de arquivos Unix não podem ter barras invertidas neles; caminhos podem, mas não arquivos individuais. No entanto, não sei ao certo como implementar melhor isso e ainda não tenho nenhuma sugestão sobre a correspondência de 0.mp3 ou 000.mp3 de tipos de nomes de arquivos.

    
por 07.02.2018 / 21:51
1

com zsh :

autoload zmv # best in ~/.zshrc
zmv -n '0#(*.mp3)' '$1'

(remova -n (dry-run) quando feliz).

O operador # glob em zsh é como o operador de expressão regular * .

Observe que ele renomeia 0000.mp3 para .mp3 . Para evitar que você possa mudá-lo, faça:

zmv -n '0#([0-9]*.mp3)' '$1'

Recursivamente:

zmv -n '(**/)0#([0-9]*.mp3)' '$1$2'

Para remover também os caracteres () @ , como seu exemplo sugere, faça o seguinte:

zmv -n '(**/)0#([0-9]*.mp3)' '$1${2//[() @]}'

(No entanto, não removeria os caracteres dos nomes dos arquivos que não iniciam com um dígito).

    
por 08.02.2018 / 01:08

Tags