Como renomear vários arquivos sequencialmente na linha de comando?

15

Como renomear o arquivo como abaixo

AS1100801000002.RAW7AGS 
AS1100801001008.RAW7AH4
AS1100801002001.RAW7AH9
AS1100801003002.RAW7AHE
AS1100801004009.RAW7AHT
AS1100801005002.RAW7AHY
AS1100801010002.RAW7AJ3

para novo nome

AS1.txt
AS2.txt
AS3.txt
AS4.txt
AS5.txt
AS6.txt
AS7.txt
kamaruz85
fonte

Respostas:

22

A renameferramenta que acompanha o Ubuntu é bastante interessante nesse tipo de coisa. Você pode incorporar pequenas expressões Perl assim:

rename -n 's/.+/our $i; sprintf("AS%d.txt", 1+$i++)/e' *

Isso apenas mostrará o que faria. Remova o -npara torná-lo um exercício de fogo vivo.

Isso basicamente funciona definindo uma variável aproximada e incrementando-a a cada arquivo que acessamos. Se você tiver mais de 10 arquivos, sugiro usar algum preenchimento zero no arquivo sprintf. O seguinte é bom até 999:

rename -n 's/.+/our $i; sprintf("AS%03d.txt", 1+$i++)/e' *

... Mas isso é fácil de expandir.

Oli
fonte
4

Não conheço um único comando ou utilitário que faria isso, mas é fácil o suficiente com um loop simples:

N=1
for X in AS*RAW*; do
  mv $X AS$N.txt
  N=$(($N+1))
done
Paulo
fonte
3

Para melhorar a resposta do @ Oli , a versão 1.600 da renameferramenta de Aristóteles Pagaltzis, na verdade, possui um contador ,.$N

Então tudo que você precisa é,

rename 's/AS.*/AS$N/' *

Para instalar,

  1. brew install renameou Faça o download do script
  2. Salve-o em um diretório no caminho do sistema (normalmente /usr/local/bin/brewou /usr/bin)
Atav32
fonte
3
Esta parece ser uma ferramenta diferente com o mesmo nome. O padrão do Ubuntu renameé nome do arquivo. Isso pode ser melhor, mas convém adicionar instruções de instalação para tornar essa resposta mais valiosa.
Oli
11
@ Oli boa chamada! Atualizada.
Atav32
2

renamepermite atribuir diretamente a $_, o que é ideal para esse problema.

Embora os argumentos de código que passam ao Perl renameutilidade muitas vezes executar a correspondência e substituição (com s/), e é totalmente aceitável para resolver este problema dessa forma , não há realmente nenhuma necessidade de que, em casos como este, onde você não está realmente examinar ou reutilizando o texto dos antigos nomes de arquivos. renamepermite escrever praticamente qualquer código Perl, e ele não precisa ser incorporado s/ /e. Eu sugiro usar um comando como este:

rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' *

Ou, se você desejar cortar alguns caracteres:

rename -n '$_ = sprintf "AS%02d.txt", ++our$i' *

(Pode ser ainda mais curto, mas não sem sacrificar a clareza.)

Ambos os comandos fazem a mesma coisa. Cada um mostra quais operações de renomeação seriam realizadas. Depois de experimentar e ficar satisfeito com os resultados, execute-o novamente sem a -nopção Como está escrito, isto produziria os nomes de arquivos AS01.txt, AS02.txt, ..., AS10.txt, AS11.txte assim por diante. Você pode modificá-los conforme necessário e depois remover apenas -nquando gostar do que vê.

Se você deseja preencher uma largura maior que 2, substitua 2por um número maior. Por exemplo, se por algum motivo você quiser nomes de arquivos como AS00000000000001.txt, substitua %02dpor %014d. Se você não desejar preenchimento - mesmo que isso faça com que seus arquivos apareçam em ordem não numérica quando você os listar mais tarde! -, poderá substituí-lo %02dpor apenas %d.

Como é que isso funciona? Seu shell se expande * para uma lista de arquivos antes mesmo de executar o renamecomando. A lista é classificada lexicograficamente (isto é, alfabeticamente) de acordo com as configurações atuais de localidade. renamerecebe os nomes dos arquivos como argumentos da linha de comando e os processa na ordem em que estão listados. A expressão é ++$iavaliada como um maior que o valor atual da variável $ie também define a variável $ipara esse valor recém-incrementado. Esse valor é passado para sprintf, que o formata e o coloca dentro de outro texto. Este texto é atribuído diretamente à variável especial $_, que contém o nome do arquivo. Como os renamearquivos de processos estão na ordem em que são passados ​​como argumentos, eles são numerados de acordo.


Você deve ter notado a semelhança com a resposta de Oli !

Ambos declaram e incrementam uma variável de contador e usam sprintfessencialmente da mesma maneira para incorporar o valor desse contador, preenchido à esquerda com zeros, no outro texto dos novos nomes de arquivos. (As informações em qualquer resposta sobre como almofada com zeros - e alterar a largura estofamento -. Mesmo se aplica igualmente a ambos) A razão que eles são tão semelhantes é que o método em que a resposta mais velho está realmente fazendo apenas isso 1 , mas com etapas extras que são úteis para muitos problemas, mas não são realmente necessárias para este.

Para comparação, veja como é o segundo comando dessa resposta se modificado para usar o estilo que usei aqui (e para preencher uma largura de 2, como fiz aqui, em vez de 3):

rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' *

A parte entre s/.+/e /enesse comando agora é a mesma que a expressão que atribuo $_(ou seja, o código no lado direito do =operador) no primeiro comando nesta resposta.

  • O s/ operador tenta corresponder o texto (nomes de arquivo dos quais o seu shell expandiu *e passou como argumentos da linha de comando quando executado rename) com uma expressão regular e executa a substituição. /está sendo usado como um delimitador para separar as diferentes partes da sexpressão. A primeira parte,, .+é a expressão regular; ele corresponde qualquer um caractere ( .) , e fá-lo uma ou mais vezes ( +) . Como os nomes de arquivos nunca estão vazios - eles sempre têm pelo menos um caractere - esta é uma maneira de corresponder a qualquer nome de arquivo 1 .
  • Em seguida, ele produz texto de cada correspondência - ou seja, de cada nome de arquivo inteiro - consistindo em our $i; sprintf "AS%02d.txt", ++$i. Isso produz o novo nome do arquivo. Normalmente, usa-se s/para produzir texto que seja (a) substituindo texto que corresponde apenas a parte do nome do arquivo ou (b) com base no texto correspondente de alguma forma (por exemplo, ele pode usar uma variável especial como $&essa que se expande para o jogo). Nesse caso, porém, o texto correspondente não está sendo usado.
  • Normalmente, o texto substituído our $i; sprintf "AS%02d.txt", ++$iseria usado como um nome de arquivo, não executado como código. Mas o /esinalizador no final faz com que o texto seja tratado como código-fonte Perl e avaliado, e usa o valor produzido com isso (nesse caso, o valor de retorno da função interna do Perl sprintf) como o novo nome do arquivo.

Embora eu acho que o método que eu tenho mostrado aqui é uma abordagem mais clara e mais simples para este problema do que qualquer método que usa s/com /e, é bom estar ciente de que a técnica, porque é bem adequado para uma série de outros renomear problemas de arquivo onde todos ou parte dos nomes de arquivos originais é examinada e / ou mantida. Eu recomendo este post de Oli (que também escreveu essa resposta ), que inclui alguns exemplos.

Uma técnica, não é uma diferença no comportamento dos $_ =comandos e os s/ /ecomandos. Na expressão regular .+, não é exatamente verdade que .corresponde a qualquer caractere, porque não corresponde a uma nova linha . Você provavelmente não deve usar nomes de arquivos com novas linhas, mas pode e, ocasionalmente, um arquivo é nomeado dessa maneira por acidente. Se você quiser, compare a saída com rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' $'foo\nbar'a de rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' $'foo\nbar'. Para fazer .corresponder uma nova linha, use a sbandeira, que fica no final (com e). Ou seja, escreva /seno final em vez de /e.

Eliah Kagan
fonte
0

Suponha que os arquivos que você deseja renomear estejam ~/Adire esses sejam os únicos arquivos nesta pasta;

n=0
for f in $( ls ~/Adir | sort ) ; do
    n=$(( n+1 ))
    mv -n "$f" "AS${n}.txt"
done

Este script examinará cada arquivo ~/Adire renomeá-lo para AS1.txt, AS2.txt, ...se o arquivo não existir (não haverá substituição). É por isso que você deve se certificar de que esses são os únicos arquivos presentes ~/Adir. O sortcomando é apenas no caso de você desejar que os arquivos mantenham a ordem inicial.

Edwin
fonte
0

Embora o OP exija uma opção de linha de comando, ele também está disponível como uma opção de GUI no Nautilus e é bastante fácil.

Selecione todos os arquivos necessários e pressione F2. Existe uma opção chamada Números automáticos. Você pode anexá-lo ao texto necessário.

Sandeep C
fonte