Renomeando vários arquivos usando sed

Renomeando vários arquivos usando sed

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

Quero substituir 05.02.01.14.00a peça por 05_02_01_14_00. Portanto, a saída final são 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?

Responder1

Basicamente, você deseja substituir um ponto por um sublinhado, exceto o último.

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

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

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

Responder2

O utilitário perlbaseado em - pode usar qualquer instrução para renomear arquivos, não apenas o operador de pesquisa e substituição ou o operador de tradução (apenas certifique-se de definir como deseja que o arquivo seja renomeado).renameperls///y//$_

De man rename:

"renomear" renomeia os nomes de arquivos fornecidos de acordo com a regra especificada como primeiro argumento. O argumento perlexpr é uma expressão Perl que se espera modificar a $_string em Perl para pelo menos alguns dos nomes de arquivos especificados. Se um determinado nome de arquivo não for modificado pela expressão, ele não será renomeado. Se nenhum nome de arquivo for fornecido na linha de comando, os nomes dos arquivos serão lidos por meio da entrada padrão.

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 todos os pontos ( .) são substituídos por sublinhados. Finalmente, $_está definido como "$b.$e".

Saída (com a -vopção detalhada):

$ 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

Aliás, use -nao testar suas renamedeclarações. Mais de man rename:

-n, -não não

Nenhuma ação: imprima os nomes dos arquivos a serem renomeados, mas não renomeie.

perl renameestá disponível empacotado para a maioria das distros (por exemplo, o renamepacote no Debian), ou emhttps://metacpan.org/release/File-Rename

informação relacionada