Como renomear vários arquivos em um diretório ao mesmo tempo


12

Eu tenho diretório dizer /var/tmp/abcque tem 4 arquivos:

12345-ram-3e3r5-io9490-89adu9.csv
45434-dam-qwe35-to9490-43adu9.csv
11234-cam-yy3r5-ro9490-85adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv

Quero renomear todos os arquivos CSV (encontrar todos os arquivos e renomeá-los) da maneira mais curta possível (provavelmente de uma linha) para isso:

XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

Respostas:


15

rename -n 's/(\w+)/XXXXX/' *.csv

remova o -nquando estiver feliz.


2
Para uma versão adequada do rename. Suponho que este seja o de Larry Wall rename, do renamepacote no Debian e derivado (e IIRC prenameem sistemas de persuasão do RedHat). Uma ferramenta muito útil.
Xenoid 14/05/19

2
perl-renameno arch linux
lesmana # 14/19

1
@SHawarden, tentei executar o comando e ler a parte relevante da página de manual para entender o padrão de substituição, mas ao adicionar o verbosesinalizador, ele não produz nada e não executa as alterações no nome do arquivo, mesmo que o caminho atual tenha arquivos com nomes semelhantes a 12345_foo.csv. Preciso executar alguma tarefa adicional para fazê-la funcionar (atualmente no Fedora 30)? É uma abordagem mais limpa do que repetir. Desde já, obrigado!
Danieldeveloper001

3
@ danieldeveloper001 Você usou renameou prename? Veja meu comentário acima. man {the command}lista os autores no final.
Xenoid 14/05/19

2
Isso funciona apenas em sistemas derivados do Debian. Os sistemas derivados do Fedora têm um renamecomando completamente diferente ; consulte unix.stackexchange.com/a/238862/135943
Wildcard

11

Experimentar:

for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done

Como funciona:

  • for f in *.csv; do

    Isso inicia um loop sobre todos os *.csvarquivos.

  • mv -i -- "$f" "XXXXX-${f#*-}"

    Isso renomeia os arquivos como você deseja, solicitando interativamente antes de substituir qualquer arquivo.

  • done

    Isso marca o fim do loop.

Exemplo:

$ ls -1
11234-cam-yy3r5-ro9490-85adu9.csv
12345-ram-3e3r5-io9490-89adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv
45434-dam-qwe35-to9490-43adu9.csv
$ for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done
$ ls -1
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

4

Gostei do pequeno desafio que você postou, então aqui está a minha solução. Estou assumindo que todos os seus arquivos começam com 5 caracteres numéricos, então, usando o comando recortar para substituir os arquivos numéricos iniciais por "XXXXX".

Abaixo, os arquivos antes do comando.

-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 11111_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 12345_baz_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml

Abaixo, o comando one liner.

for src in *.csv; do dst=XXXXX$(echo $src| cut -c6-); mv $src $dst; done;

Abaixo, os arquivos após o comando.

-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 XXXXX_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 XXXXX_baz_file.csv

É isso que você está procurando? :)

Referências:

Loop através da saída do comando no bash

Substrings no bash


2
O Bash pode fazer esse tipo de manipulação de strings, sem necessidade de bifurcar um novo processo para cada um, por favor, responda a outra como.
chx 14/05/19

1
O @chx já viu as outras respostas e adquiriu um pouco de conhecimento, mas obrigado por apontá-las. Você poderia por favor elaborar no need to fork a new process for each?
Danieldeveloper001

3
cuté um binário separado ( /usr/bin/cut) e sua execução consome mais recursos do que o uso de shell embutido.
Chx 15/05/19

2
Entendo, realmente importa se a intenção está renomeando muitos arquivos. Obrigado pelo esclarecimento!
Danieldeveloper001

1

sem garfos:

ls | perl -lne '$suf=substr($_,6); rename $_, "XXXXX-$suf"'

Quando você usa um loop de shell, os mvgarfos uma vez por arquivo. O renamecomando do Perl não.

(O comando renomear do Perl tem algumas restrições, mas nesse caso específico essas restrições não se aplicam.)

Quanto ao renamecomando mostrado anteriormente, sim, isso funciona, mas você tem toda essa confusão entre dois tipos diferentes de renomeação e assim por diante. Se você tem o caminho certo, ótimo, mas se não, isso também funciona.

Se você não possui o comando perl-rename e não pode instalá-lo, basta fazer o seguinte:

ls | perl -lne '$old=$_; s/(\w+)/XXXXX/; rename $old, $_'

Como você pode ver, isso usa a mesma substituição mostrada na resposta superior. Claro que o perl-renomeação tem outros sinos e assobios (a resposta superior mencionado, -njá, então não há -0, -fe assim por diante), e quanto mais deles você precisa, quanto mais você deve instalar que em vez de rolar seus próprios dessa maneira .


As implementações usuais de um tubo terão garfos.
1759 muru

Eu quis dizer, "não bifurcará uma vez por arquivo a ser renomeado", diferentemente do shell, onde o "mv" bifurca / usr / bin / mv ou o que for. Isso ocorre porque o comando "renomear" é um comando interno do perl que chama diretamente rename () na libc. Claro que tem algumas restrições, mas neste exemplo específico essas restrições não se aplicam.
Sitaram 17/05/19

1
Isso também vale para o renamecomando (a resposta principal , também usa Perl), então talvez você deva adicionar um pouco mais de explicação do que simplesmente "sem garfos" na resposta.
muru 17/05/19
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.