O script python abaixo faz o trabalho. Arquivos ocultos são armazenados separadamente em uma pasta, bem como arquivos sem extensão.
Como ele pode ser usado para uma variedade maior de finalidades, adicionei algumas opções:
- Você pode definir extensões que deseja excluir da "reorganização". Se você deseja simplesmente mover tudo, defina
exclude = ()
- Você pode escolher o que fazer com pastas vazias (
remove_emptyfolders = True
ou False
)
- Caso você queira copiar os arquivos em vez de movê- los, substitua a linha:
shutil.move(subject, new_dir+"/"+name)
por:
shutil.copy(subject, new_dir+"/"+name)
O script:
#!/usr/bin/env python3
import os
import subprocess
import shutil
# --------------------------------------------------------
reorg_dir = "/path/to/directory_to_reorganize"
exclude = (".jpg") # for example
remove_emptyfolders = True
# ---------------------------------------------------------
for root, dirs, files in os.walk(reorg_dir):
for name in files:
subject = root+"/"+name
if name.startswith("."):
extension = ".hidden_files"
elif not "." in name:
extension = ".without_extension"
else:
extension = name[name.rfind("."):]
if not extension in exclude:
new_dir = reorg_dir+"/"+extension[1:]
if not os.path.exists(new_dir):
os.mkdir(new_dir)
shutil.move(subject, new_dir+"/"+name)
def cleanup():
filelist = []
for root, dirs, files in os.walk(reorg_dir):
for name in files:
filelist.append(root+"/"+name)
directories = [item[0] for item in os.walk(reorg_dir)]
for dr in directories:
matches = [item for item in filelist if dr in item]
if len(matches) == 0:
try:
shutil.rmtree(dr)
except FileNotFoundError:
pass
if remove_emptyfolders == True:
cleanup()
SE houver risco de sobrescrever arquivos duplicados indesejados
À custa de algumas linhas extras, podemos evitar a substituição de possíveis duplicatas. Com o código abaixo, duplicatas serão renomeadas como:
duplicate_1_filename, duplicate_2_filename
etc.
O script:
#!/usr/bin/env python3
import os
import subprocess
import shutil
# --------------------------------------------------------
reorg_dir = "/path/to/directory_to_reorganize"
exclude = (".jpg") # for example
remove_emptyfolders = True
# ---------------------------------------------------------
for root, dirs, files in os.walk(reorg_dir):
for name in files:
subject = root+"/"+name
if name.startswith("."):
extension = ".hidden_files"
elif not "." in name:
extension = ".without_extension"
else:
extension = name[name.rfind("."):]
if not extension in exclude:
new_dir = reorg_dir+"/"+extension[1:]
if not os.path.exists(new_dir):
os.mkdir(new_dir)
n = 1; name_orig = name
while os.path.exists(new_dir+"/"+name):
name = "duplicate_"+str(n)+"_"+name_orig
n = n+1
newfile = new_dir+"/"+name
shutil.move(subject, newfile)
def cleanup():
filelist = []
for root, dirs, files in os.walk(reorg_dir):
for name in files:
filelist.append(root+"/"+name)
directories = [item[0] for item in os.walk(reorg_dir)]
for dr in directories:
matches = [item for item in filelist if dr in item]
if len(matches) == 0:
try:
shutil.rmtree(dr)
except FileNotFoundError:
pass
if remove_emptyfolders == True:
cleanup()
EDITAR
Com o OP em mente, todos esquecemos de adicionar uma instrução sobre como usar. Como perguntas duplicadas podem ( e realmente aparecem), elas podem ser úteis.
Como usar
- Copie qualquer um dos scripts para um arquivo vazio, salve-o como
reorganize.py
Na seção principal do script, defina o diretório de destino (com os arquivos a serem reorganizados):
reorg_dir = "/path/to/directory_to_reorganize"
(use aspas se o diretório contiver espaços)
possíveis extensões que você deseja excluir (provavelmente nenhuma, como abaixo):
exclude = ()
e se você deseja remover as pastas vazias depois:
remove_emptyfolders = True
Execute o script com o comando:
python3 /path/to/reorganize.py
Nota: se você deseja copiar os arquivos em vez de mover , substitua:
shutil.move(subject, new_dir+"/"+name)
por:
shutil.copy(subject, new_dir+"/"+name)
Por favor, tente primeiro uma pequena amostra.
-iname '*.*'
deveria cuidar dos casos de canto que eu estava preocupado com ... boa idéia!*.fig.bak
ou.profile/.bashrc
, mas deve lidar apenas com arquivos com extensões, pelo menos. Obrigado.Calculando a lista de extensões (depois da mudança):
Calculando a lista de extensões (antes de mover):
(neste último exemplo, estamos calculando o número de arquivos para cada extensão e classificando-o)
fonte
ls -X | grep -Po '(?<=\.)(\w+)$'
foi minha primeira ideia para obter a lista ordenada de extensões. Isso é muito ruim? O que você sugere?ls -X
faz. Sobre o motivo pelo qual eu recomendols
, consulte unix.stackexchange.com/q/128985/70524 e unix.stackexchange.com/q/112125/70524 . Para conseguir o que você faz, eu usaria um caminho mais longo:find . -type f -name '*?.?*' -print0 | sed -z 's/.*\.//' | sort -zu
(com um opcional| uniq -cz
, se forem necessárias contagens). Efind ... -print0 | gawk -v RS='\0'
(mesmo que isso não seja muito portátil ) para o primeiro.Experimente este script de shell.
fonte
filepath
withfile
. Eu vou corrigir isso diretamente.for file in "$src"/*?.?*; do ..
read
pode ter um comportamento inesperado. Você também deve citar as variáveis nos comandos mkdir e mv.for i in *; do printf "%s\n" "$i"; done; for i in $(ls -d); do printf "%s\n" "$i"; done
Se você tiver renomeado / nome de usuário do Perl instalado:
fonte