Poniższy skrypt python wykonuje to zadanie. Ukryte pliki są przechowywane osobno w folderze, a także pliki bez rozszerzenia.
Ponieważ można go wykorzystać do szerszego zakresu celów, dodałem kilka opcji:
- Możesz ustawić rozszerzenia, które chcesz wykluczyć z „reorganizacji”. Jeśli chcesz po prostu przenieść wszystko, ustaw
exclude = ()
- Możesz wybrać, co zrobić z pustymi folderami (
remove_emptyfolders = True
lub False
)
- Jeśli chcesz skopiować pliki zamiast je przenieść , zamień wiersz:
shutil.move(subject, new_dir+"/"+name)
przez:
shutil.copy(subject, new_dir+"/"+name)
Scenariusz:
#!/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()
JEŚLI istnieje ryzyko niepożądanego zastąpienia zduplikowanych plików
Kosztem kilku dodatkowych wierszy możemy zapobiec nadpisywaniu możliwych duplikatów. W poniższym kodzie duplikaty zostaną przemianowane na:
duplicate_1_filename, duplicate_2_filename
itp.
Scenariusz:
#!/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()
EDYTOWAĆ
Mając na uwadze OP, wszyscy zapomnieliśmy dodać instrukcję obsługi. Ponieważ mogą pojawiać się ( i pojawiają się) zduplikowane pytania , może być jednak przydatne.
Jak używać
- Skopiuj jeden ze skryptów do pustego pliku i zapisz go jako
reorganize.py
W sekcji head skryptu ustaw katalog docelowy (z plikami do reorganizacji):
reorg_dir = "/path/to/directory_to_reorganize"
(użyj cudzysłowów, jeśli katalog zawiera spacje)
możliwe rozszerzenia, które chcesz wykluczyć (prawdopodobnie żadne, jak poniżej):
exclude = ()
a jeśli chcesz później usunąć puste foldery:
remove_emptyfolders = True
Uruchom skrypt za pomocą polecenia:
python3 /path/to/reorganize.py
Uwaga: jeśli chcesz skopiować pliki zamiast przenieść , zastąp:
shutil.move(subject, new_dir+"/"+name)
przez:
shutil.copy(subject, new_dir+"/"+name)
Spróbuj najpierw na małej próbce.
-iname '*.*'
powinien dbać o przypadkach narożnych Martwiłem się o ... fajny pomysł!*.fig.bak
lub.profile/.bashrc
, ale powinien obsługiwać tylko pliki z rozszerzeniami, przynajmniej. Dzięki.Obliczanie listy rozszerzeń (po przeniesieniu):
Obliczanie listy rozszerzeń (przed przeniesieniem):
(w tym ostatnim przykładzie obliczamy liczbę plików dla każdego rozszerzenia i sortujemy je)
źródło
ls -X | grep -Po '(?<=\.)(\w+)$'
był moim pierwszym pomysłem, aby uzyskać posortowaną listę rozszerzeń. Czy to bardzo źle? Co sugerujesz?ls -X
robi. Dlaczego nie polecamls
, zobacz unix.stackexchange.com/q/128985/70524 i unix.stackexchange.com/q/112125/70524 . Aby osiągnąć to, co robisz, wybrałbym dłuższą drogę:find . -type f -name '*?.?*' -print0 | sed -z 's/.*\.//' | sort -zu
(z opcjonalnym| uniq -cz
, jeśli potrzebne są liczenia). Ifind ... -print0 | gawk -v RS='\0'
(choć nie jest to zbyt przenośne ) po raz pierwszy.Wypróbuj ten skrypt powłoki.
źródło
filepath
zfile
. Naprawię to bezpośrednio.for file in "$src"/*?.?*; do ..
read
może mieć nieoczekiwane zachowanie. Powinieneś również cytować zmienne w komendach mkdir i mv.for i in *; do printf "%s\n" "$i"; done; for i in $(ls -d); do printf "%s\n" "$i"; done
Jeśli masz zainstalowaną nazwę / nazwę Perla:
źródło