Renomeando vários arquivos usando sed

0

Eu tenho o seguinte conjunto de arquivos

top_axi_256_wrapper_05.02.01.14.00_sample06.tgz
top_axi_128_wrapper_05.02.01.14.00_sample06.tgz

Eu quero substituir 05.02.01.14.00 part por 05_02_01_14_00 . Então a saída final é os seguintes arquivos renomeados

top_axi_256_wrapper_05_02_01_14_00_sample06.tgz
top_axi_128_wrapper_05_02_01_14_00_sample06.tgz

Meu diretório também pode conter os seguintes tipos de nomes de arquivos.

a72_a_0.0.0_0.00.04_ac_dc.tgz

Aqui, desejo renomear o arquivo para

a53_1c_256K_a_0_0_0_0_00_04_ac_dc.tgz

Como fazer isso?

    
por Ramneek Singh Kakkar 17.05.2016 / 09:21

2 respostas

2

Você basicamente quer substituir um ponto por um sublinhado, exceto pelo último.

Você pode usar a expansão de parâmetro do bash para isso:

for file in * ; do
    replace_all=${file//./_}
    newname=${replace_all%_*}.${replace_all##*_}
    mv "$file" "$newname"
done
  • //./_ significa substituir todos os pontos por sublinhados
  • %_* significa remove tudo após o último sublinhado
  • ##*_ significa remover tudo até o último sublinhado

Ou você pode salvar a extensão primeiro, depois removê-la, substituir todos os pontos por sublinhados e adicionar a extensão novamente. Deixado como um exercício para o leitor.

    
por 17.05.2016 / 09:36
0

O utilitário perl -based rename pode usar qualquer instrução perl para renomear arquivos, não apenas o operador s/// de pesquisa e substituição ou o operador y// translation (apenas certifique-se de definir $_ para o que você deseja que o arquivo seja renomeado para).

De man rename :

"rename" renames the filenames supplied according to the rule specified as the first argument. The perlexpr argument is a Perl expression which is expected to modify the $_ string in Perl for at least some of the filenames specified. If a given filename is not modified by the expression, it will not be renamed. If no filenames are given on the command line, filenames will be read via standard input.

Por exemplo:

rename 'my($b,$e) = m/^(.*)\.([^.]+)$/; $b =~ s/\./_/g; $_="$b.$e"' files

Isso divide os nomes dos arquivos em nome base ($ b) e extensão ($ e). $ b então tem todos os períodos ( . ) substituídos por sublinhados. Finalmente, $_ está definido como "$b.$e" .

Saída (com a opção -v verbose):

$ touch top_axi_256_wrapper_05.02.01.14.00_sample06.tgz \
    top_axi_128_wrapper_05.02.01.14.00_sample06.tgz \
    a72_a_0.0.0_0.00.04_ac_dc.tgz

$ rename -v 'my($b,$e) = m/^(.*)\.([^.]+)$/; $b =~ s/\./_/g; $_="$b.$e"' *
a72_a_0.0.0_0.00.04_ac_dc.tgz renamed as a72_a_0_0_0_0_00_04_ac_dc.tgz
top_axi_128_wrapper_05.02.01.14.00_sample06.tgz renamed as top_axi_128_wrapper_05_02_01_14_00_sample06.tgz
top_axi_256_wrapper_05.02.01.14.00_sample06.tgz renamed as top_axi_256_wrapper_05_02_01_14_00_sample06.tgz

BTW, use -n ao testar suas instruções rename . Mais de man rename :

-n, -nono

No action: print names of files to be renamed, but don't rename.

perl rename está disponível empacotado para a maioria das distros (por exemplo, o pacote rename no Debian), ou de link

    
por 17.05.2016 / 11:21

Tags