Como renomear múltiplos arquivos em um diretório em algum padrão no Linux?

5

Eu tenho um diretório que possui arquivos com nomes aleatórios. O que eu quero fazer é renomear os arquivos com file1, file2 e assim por diante.O nome do arquivo lexicographically menor deve ser numerado com menor número. Como posso fazer isso?

    
por banarun 01.07.2013 / 05:30

4 respostas

8

Um script simples deve fazê-lo.

#!/usr/bin/env bash

count=0
for i in *; do
    mv "${i}" file${count}.'echo "${i}" | awk -F. '{print $2}''
    ((++count))
done

Para ajudar com uma explicação linha a linha:

  1. Localização do shell bash que está sendo executado, determinado por sua variável ambiental.
  2. Defina a variável "count" para 0
  3. Cria um loop, iterando a saída do comando ls (classificado em ordem alfabética por padrão).
  4. Move (ou seja, renomeia) o arquivo "i" (atual no loop) para file#.ext . O "#" é o número atual em "count" e o material após o "." é uma maneira rápida de obter a extensão de arquivo atual (para que isso funcione em uma pasta de várias extensões de arquivo).
  5. Incrementar a variável do contador

loop, loop, loop

  1. pronto!

Nota :

  1. Isto é executado em qualquer diretório que você esteja executando. Então, como um script, você deseja adicionar um argumento de linha de comando. Em vez disso, eu abriria um terminal, navegaria até o diretório para fazer isso e executaria o seguinte (exatamente):

    for i in *; do mv "${i}" "file${count}".'echo "${i}" | 
      awk -F. '{print $2}''; ((++count)); done
    
  2. Isto presume que você tenha apenas nomes de arquivos como "file.txt" e "this.is.a.file.txt"

por 01.07.2013 / 06:08
3

Você pode usar este script python:

#!/usr/bin/python
import os
#enter the path to the folder: relative or absolute
direc = raw_input('Enter the path to directory: ')
os.chdir(os.path.join(os.getcwd(),direc))
files = os.listdir('.')
def func(x):
    return map(str.lower,os.path.splitext(x))
files.sort(key = func)
for i,x in enumerate(files, 1):
    name, ext = os.path.splitext(x)
    os.rename(x, 'file{}{}'.format(i,ext))
    
por 01.07.2013 / 06:12
2

Uma bash (semelhante à solução do nerdwaller, mas sem subcampos e garfos para awk ):

#!/usr/bin/bash

shopt -s nullglob

count=0
for i in *; do
    mv -nv -- "$i" "file$((++count))"
done

Comutadores para mv :

  • -n para nenhum estroboscópio: não sobrescreverá um arquivo existente. Remova-o se realmente quiser sobrescrever arquivos (pode não estar disponível dependendo da sua versão de mv ),
  • -v para verbose: diga o que está fazendo. Altamente opcional (mas gosto de ter estas linhas no meu terminal para impressionar os meus colegas),
  • -- para o final das opções: sem isso, e se um nome de arquivo começar com um hífen, isso confunderia mv , já que tentaria interpretá-lo como uma opção. Pode não estar disponível, dependendo da sua versão de mv . Use-o se disponível!

Também estou usando o comportamento opcional do shell nullglob para que, se não houver arquivos, você não receba nenhum erro (o loop não será executado, pois o * seria expandido para nada neste caso) .

Se você precisa lidar com extensões também (como na versão do nerdwaller), você não precisa awk , tudo pode ser feito em bash :

#!/usr/bin/bash

shopt -s nullglob

count=0
for i in *; do
    mv -nv -- "$i" "file$((++count)).${i##*.}"
done

Observe que a numeração não terá nenhum zeros à esquerda, de modo que você obterá os arquivos assim chamados:

file1
file2
...
file10
file11
...

e isso pode estragar a ordem dos arquivos nas listagens. Se você precisar de zeros iniciais também:

#!/usr/bin/bash

shopt -s nullglob

files=( * )

lz=0
for ((n=${#files[@]};n;n/=10)); do ((++lz)); done

count=0
for i in "${files[@]}"; do
    printf -v n "%0${lz}d" $((++count))
    mv -nv -- "$i" "file$n"
done

E se você quiser manter a extensão do arquivo original, substitua a linha

mv -nv -- "$i" "file$n"

com

mv -nv -- "$i" "file$n.${i##*.}"

Advertências .

  • Como isso usa bash globbing, pode ser muito lento se você tem um grande número de arquivos em seu diretório (globbing pode levar algum tempo).
  • Isso renomeia tudo, incluindo diretórios, mas não arquivos ocultos.

Curas .

  • Não tenho nenhuma solução em relação à velocidade em caso de um grande número de arquivos em bash .
  • Se você precisar descartar diretórios desse procedimento de renomeação e apenas renomear arquivos, adicione [[ -f $i ]] || continue logo após a instrução for i in *; do .
  • Se também precisar renomear arquivos ocultos, adicione shopt -s dotglob logo após a instrução shopt -s nullglob .

Se você ler até aqui, eu acho que você será capaz de criar algo que corresponda à sua própria necessidade a partir dos exemplos que lhe dei, espero usar boas bash prática (desde que você escolha resolver o problema usando bash , claro).

    
por 01.07.2013 / 17:57
1

Eu queria implementar o mesmo quando era estudante e estava estudando os Scripts Shell do Linux. então eu criei o script abaixo .. Dê uma olhada .. link

    
por 01.07.2013 / 05:53

Tags