Renomeação em lote de arquivos usando expressão regular no Unix

2

Eu tenho vários milhares de arquivos do formulário:

[número de 8 dígitos] _ [número que eu quero] _S60491_I129111.dcm.

Desejo remover tudo, exceto o número desejado, e usá-lo como nome. Em Ruby, posso chegar a esse valor com a expressão regular /^.*_(\d+)_S60491_I12911.dcm/ , mas estou tendo problemas para tentar traduzir isso para uma expressão sed que me permite substituir o nome completo do arquivo por apenas esse número entre os sublinhados. / p>

Existe uma maneira de usar sed ou outros comandos básicos do Bash para fazer o que eu quero? Se isso ajudar, o número que eu quero é apenas um contador (ou seja, ele é executado de 1 a 2100), e o número de 8 dígitos do prefixo resulta nos arquivos listados na ordem correta (ou seja, do arquivo 1 para o arquivo 2100). então eu posso estar pensando demais.

    
por ackrause 23.01.2013 / 22:15

4 respostas

1

Isso funciona para mim: for a in * ; do mv "$a" $(echo "$a" | cut -d'_' -f 2) ; done

toad:/home/hennes/work/foo>ls -l
total 0
-rw-------  1   users  0 Jan 23 22:19 12345678_023454_S60491_I129111.dcm
-rw-------  1   users  0 Jan 23 22:19 12345678_123454_S60491_I129111.dcm
-rw-------  1   users  0 Jan 23 22:19 12345678_123456_S60491_I129111.dcm

toad:/home/hennes/work/foo>for a in * ; do mv $a $(echo $a | cut -d'_' -f 2) ; done

toad:/home/hennes/work/foo>ls -l
total 0
-rw-------  1   users  0 Jan 23 22:23 023454
-rw-------  1   users  0 Jan 23 22:23 123454
-rw-------  1   users  0 Jan 23 22:23 123456

for a in * seleciona todos os arquivos. Se houver mais arquivos, um * .dcm poderá ser usado.

mv (move) muda o nome do arquivo

de $ a (o nome do arquivo selecionado para)

ao campo2 do nome, com _ usou um delimitador de campo.

Note que este script irá mover os arquivos, então os nomes dos arquivos antigos serão perdidos. Você pode usar 'cp' em vez de 'mv' para fazer uma cópia.

Se você quiser manter a extensão, adicione-a após o -f 2).
 Por exemplo. for a in * ; do cp $a $(echo $a | cut -d'_' -f 2).dcm ; done

    
por 23.01.2013 / 22:26
2

Existe uma ferramenta comumente chamada renomear ou prename instalado na maioria dos sistemas. Nos meus sistemas Debian / Ubuntu isso vem como parte do Perl. Ele permite que você use expressões regulares no estilo Perl para manipular nomes de arquivos como quiser.

Seu comando provavelmente se pareceria com isso. Eu sugiro que você passe a opção --no-act e examine a saída antes de realmente se comprometer a fazer quaisquer alterações.

prename 's/^.*_(\d+)_S60491_I12911.dcm/$1/' *
    
por 23.01.2013 / 23:16
1

Como sabemos o formato dos nomes e nenhum contém espaços:

for a in * ; do
   mv $a $(echo $a | sed 's/[^_]*_//;s/_S60491_I129111.dcm//')
done
    
por 23.01.2013 / 22:44
0

Existem muitas maneiras de fazer isso. Mas desde que você pediu sed , isso faria:

ls dcm | sed 's/^([0-9]{8}_([0-9])_S60491_I129111.dcm)/mv /g' | bash

O primeiro bit do padrão seleciona números de 8 dígitos, então você procura por qualquer dígito (desde que você não mencionou o tamanho do segundo número) e, em seguida, sua sequência à direita. e referem-se ao conteúdo dos parênteses externos e internos de escape \(...\) . Você pode substituir bash por qualquer shell neste caso.

As extensões GNU do sed permitirão que você faça também:

ls *dcm | sed 's/^([0-9]{8}_([0-9]+)_S60491_I129111.dcm)/mv /g' | bash

em que + permite a correspondência de um ou mais, em que * corresponde a zero ou mais, o que causa problemas para 12345678__S60491_I129111.dcm .

    
por 23.01.2013 / 22:43