Como posso renomear arquivos no diretório, mantendo parte do nome inalterado?

1

Eu tenho vários arquivos (cerca de 1000) nomeados como:

abcdefg123456.xyz
abcdefg123457.xyz
abcdefg123458.xyz
abcdefg123459.xyz

Alguns dos arquivos têm 4 números aleatórios adicionais e letras (em qualquer ordem) após o nome. Estes são possivelmente duplicados, mas nem sempre, então eu preciso mudá-los para o formato original para verificar se eles são duplicados ou não. Eles têm esse formato:

abcdefg123456a789.xyz
abcdefg123457b987.xyz
abcdefg123458c879.xyz
abcdefg123459d897.xyz

Ocasionalmente, há uma extensão errada também

abcdefg123456.xyzedf
abcdefg123456.xyzfed

Eu quero renomear esses arquivos para o formato original de abcdefg seguido dos 6 números originais - ou seja, para excluir os 4 números aleatórios e letras à direita e excluir a extensão à direita .xyz O que eu tenho até agora é este:

rename -n "s/[a-z][0-9]{6}.xyz/.xyz/g"  *

Mas parece que não funciona. Por algum motivo, a saída é:

abcdef.xyz (no numbers)

EDIT: Eu estava um pouco dividido entre qual resposta escolher, porque ambos ajudaram a encontrar a solução. Eu fui por stuts porque ele ajudou com a segunda parte da questão também. Mas sua ajuda é muito apreciada também por Mark Perryman - e os comentaristas também, é claro.

    
por user681866 04.01.2017 / 16:21

2 respostas

2

Solução

Para remover os 4 números / letras que precedem o ponto final de todos os arquivos, você pode usar o seguinte loop:

for file in *.xyz ; do
    NEWFILE=$(echo "$file" |sed -re 's/[a-z|0-9][a-z|0-9][a-z|0-9][a-z|0-9](\.)/\./g')
    mv -v $file $NEWFILE
done

Explicação

for file in *.xyz ; do

Faz um loop em todos os arquivos com uma extensão .xyz

NEWFILE=$(echo "$file" |sed -re 's/[a-z|0-9][a-z|0-9][a-z|0-9][a-z|0-9](\.)/\./g')

Crie uma variável chamada NEWFILE contendo o nome do arquivo depois de remover um padrão que corresponda a [a-z|0-9][a-z|0-9][a-z|0-9][a-z|0-9] (uma mistura de 4 números ou letras) e seja seguido por um ponto final ( (\.) ).

mv -v $file $NEWFILE

Mova o arquivo para o novo nome, o -v imprimirá o processo de movimentação no seguinte formato

'abcdefg123456a789.xyz' -> 'abcdefg123456.xyz'

No momento, isso não cobre a correção de extensões, mas uma solução semelhante à acima pode ser usada, mas com o comando sed sendo sed 's/\.xyz.*/\.xyz/g' .

    
por 04.01.2017 / 16:56
1

Tente

rename -n -f 's/([a-z]*[0-9]{6})[a-z0-9]{0,4}(\.xyz).*/$1$2/g'  *

Isso funciona na versão de rename lançada com debian e ubuntu (veja man page no link )

Isso substituirá os arquivos que teriam nomes duplicados.

Por que isso funciona

  • ([a-z]*[0-9]{6}) é o abcdefg123456 capturado e pode ser referido como $1 na substituição.
  • (\.xyz) é a extensão capturada e referida como $2 na substituição.
  • Todo o restante [a-z0-9]{0,4} (até 4 letras / números) e .* (qualquer coisa após a extensão) são correspondidos e, em seguida, ignorados na substituição.

Bônus Para excluir todos os arquivos que ainda não se ajustam ao seu padrão (por exemplo, se você não usou a opção Forçar acima), use find para listá-los e removê-los. (Corra sem -exec rm {} para uma corrida a seco).

find . -regextype posix-egrep -regex '.*/[a-z]*[0-9]{6}[a-z0-9]{4}\.xyz.*|[a-z]*[0-9]{6}\.xyz.*' -exec rm {}
    
por 04.01.2017 / 16:50