Como renomear vários arquivos seqüencialmente da linha de comando?

13

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
    
por kamaruz85 30.05.2013 / 03:52

5 respostas

16

A ferramenta rename que vem com o Ubuntu é bastante interessante nesse tipo de coisa. Você pode inserir pequenas expressões Perl assim:

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

Isso apenas mostrará o que ele faria. Remova o -n para torná-lo um exercício de fogo real.

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

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

... Mas isso é fácil o suficiente para expandir.

    
por Oli 07.06.2014 / 22:23
4

Eu não sei de um único comando ou utilitário que faria isso, mas é fácil fazer isso com um simples loop:

N=1
for X in AS*RAW*; do
  mv $X AS$N.txt
  N=$(($N+1))
done
    
por Paul 30.05.2013 / 04:18
2

Para melhorar a resposta do @ Oli, a ferramenta rename versão 1.600 por Aristóteles Pagaltzis na verdade tem um contador embutido, $N .

Então tudo que você precisa é,

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

Para instalar,

  1. Faça o download do script
  2. Salve-o em um diretório no caminho do sistema (geralmente /usr/local/bin/brew ou /usr/bin )
por Atav32 14.03.2017 / 03:53
2

rename permite atribuir diretamente a $_ , o que é ideal para este problema.

Embora os argumentos do código passemos para o Perl rename utilitário freqüentemente executa correspondência e substituição (com s/ ), e é totalmente aceitável para levar este problema dessa forma , não há realmente necessidade disso em casos como este onde você não está realmente examinando ou reutilizando o texto do nomes de arquivos antigos. rename permite que você escreva praticamente qualquer código Perl, e não precisa ser incorporado em s/ /e . Sugiro usar um comando como este:

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

Ou, se você sentir vontade de raspar alguns personagens:

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 um e ficar satisfeito com os resultados, execute-o novamente sem a opção -n . Conforme escrito, isso produzirá os nomes dos arquivos AS01.txt , AS02.txt , ... , AS10.txt , AS11.txt e assim por diante. Você pode modificá-los conforme necessário e, em seguida, remover apenas -n quando gostar do que vê.

Se você quiser preencher uma largura maior que 2, substitua o 2 por um número maior. Por exemplo, se por algum motivo você quisesse nomes de arquivo como AS00000000000001.txt , você substituiria %02d por %014d . Se você não quiser preenchimento algum - mesmo que isso faça seus arquivos aparecerem em ordem não numérica quando você os listar mais tarde! - então você pode substituir %02d por apenas %d .

Como isso funciona? Seu shell expande * em uma lista de arquivos antes mesmo de executar o rename comando. A lista é classificada lexicograficamente (por exemplo, alfabeticamente) de acordo com as configurações locais atuais. rename recebe os nomes dos arquivos como argumentos da linha de comandos e os processa na ordem em que estão listados. A expressão ++$i é avaliada como uma maior que o valor atual da variável $i e também define a variável $i para esse novo valor incrementado. Esse valor é passado para sprintf , que formata e coloca dentro de outro texto . Este texto é atribuído diretamente à variável especial $_ , que contém o nome do arquivo. Como o rename processa os arquivos 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 ambos usam sprintf essencialmente da mesma maneira para incorporar o valor daquele contador, preenchido à esquerda com zeros, no outro texto dos novos nomes de arquivos. (As informações em qualquer resposta sobre como preencher com zeros - e alterar a largura de preenchimento - também se aplicam igualmente a ambos.) A razão pela qual elas são tão semelhantes é que o método na resposta mais antiga está realmente fazendo exatamente 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, aqui está o segundo comando dessa resposta se for 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 /e nesse comando agora é igual à expressão que atribuo a $_ (ou seja, o código no lado direito do operador = ) no primeiro comando em esta resposta.

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

Embora eu ache que o método que mostrei aqui seja uma abordagem mais clara e simples para esse problema do que qualquer método que use s/ com /e , é bom estar ciente dessa técnica , porque é bem adequado para uma série de outros problemas de renomeação de arquivos, onde todos ou parte dos nomes de arquivos originais são examinados e / ou retidos. Eu recomendo este post no blog por Oli (que também escreveu essa resposta ), que inclui alguns desses exemplos.

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

    
por Eliah Kagan 20.03.2018 / 06:34
0

Suponha que os arquivos que você deseja renomear estejam em ~/Adir , e estes são os únicos arquivos nesta pasta, então:

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

Este script irá olhar para cada arquivo em ~/Adir e renomeá-lo para AS1.txt, AS2.txt, ... se o arquivo não existir (não haverá sobrescritos). É por isso que você deve se certificar de que esses são os únicos arquivos em ~/Adir . O comando sort é apenas para o caso de você querer que os arquivos mantenham o pedido inicial.

    
por edwin 30.05.2013 / 04:24