Я ищу путь (предпочтительно терминал) для организации более чем 1 000 шрифтов их первой буквой.
В основном создайте каталоги A-Z, #
затем переместите файлы шрифтов в те каталоги на основе их имени файла первый символ. Шрифты, которые начинаются с номеров [0-9] или других специальных символов, которые будут перемещены в #
каталог.
Последняя опция Python:
#!/usr/bin/env python3
import os
import sys
import shutil
def path(dr, f): return os.path.join(dr, f)
dr = sys.argv[1]
for f in os.listdir(dr):
fsrc = path(dr, f)
if os.path.isfile(fsrc):
s = f[0]; target = path(dr, s.upper()) if s.isalpha() else path(dr, "#")
if not os.path.exists(target):
os.mkdir(target)
shutil.move(fsrc, path(target, f))
move_files.py
Выполните его с каталогом как аргумент:
python3 /path/to/move_files.py /path/to/files
Сценарий только создаст (sub) каталог (-ies) (верхний регистр), если он будет на самом деле необходим
Сценарий:
перечисляет файлы, добирается, первый символ (определяет sourcepath):
for f in os.listdir(dr):
s = f[0]; fsrc = path(dr, f)
проверки, если объект является файлом:
if os.path.isfile(fsrc):
определяет целенаправленную папку или для того, если первый символ является альфой или нет:
target = path(dr, s.upper()) if s.isalpha() else path(dr, "#")
проверки, если папка уже существует или нет, создают ее если нет:
if not os.path.exists(target):
os.mkdir(target)
перемещает объект в его соответствующую папку:
shutil.move(fsrc, path(target, f))
Если Вы не возражаете против zsh, функции и нескольких zmv
команды:
mmv() {echo mkdir -p "${2%/*}/"; echo mv -- "$1" "$2";}
autoload -U zmv
zmv -P mmv '([a-zA-Z])(*.ttf)' '${(UC)1}/$1$2'
zmv -P mmv '([!a-zA-Z])(*.ttf)' '#/$1$2'
Эти mmv
функция делает каталог и перемещает файл. zmv
затем обеспечивает сопоставление с образцом и замену. Во-первых, перемещая имена файлов, запускающиеся с алфавита, затем все остальное:
$ zmv -P mmv '([a-zA-Z])(*.ttf)' '${(UC)1}/$1$2'
mkdir -p A/
mv -- abcd.ttf A/abcd.ttf
mkdir -p A/
mv -- ABCD.ttf A/ABCD.ttf
$ zmv -P mmv '([!a-zA-Z])(*.ttf)' '#/$1$2'
mkdir -p #/
mv -- 123.ttf #/123.ttf
mkdir -p #/
mv -- 七.ttf #/七.ttf
Выполнение снова без echo
в mmv
определение для фактического выполнения перемещения.
Я не разрабатывал хороший способ сделать верхний регистр имен каталогов (или перемещать файлы с прописными буквами), хотя Вы могли сделать это впоследствии с rename
...
mkdir {a..z} \#; for i in {a..z}; do for f in "$i"*; do if [[ -f "$f" ]]; then echo mv -v -- "$f" "$i"; fi; done; done; for g in [![:alpha:]]*; do if [[ -f "$g" ]]; then echo mv -v -- "$g" \#; fi; done
или больше четко:
mkdir {a..z} \#;
for i in {a..z}; do
for f in "$i"*; do
if [[ -f "$f" ]]; then
echo mv -v -- "$f" "$i";
fi
done
done
for g in [![:alpha:]]*; do
if [[ -f "$g" ]]; then
echo mv -v -- "$g" \#
fi
done
Удаляют echo
после тестирования для фактического перемещения файлов
, И затем
rename -n 'y/[a-z]/[A-Z]/' *
удаляют -n
, если это выглядит хорошим после тестирования и выполненным снова.
Отобразите каждое имя файла на имя каталога с помощью tr
, затем mkdir
и mv
:
find /src/dir -type f -print0 |
xargs -0 -I{} bash -c \
'dir=/dest/$(basename "{}" | cut -c1 | tr -C "a-zA-Z\n" "#" | tr "a-z "A-Z"); mkdir -p $dir; mv "{}" $dir'
Следующие команды в рамках каталога, содержащего шрифты, должны работать, если Вы хотите использовать снаружи каталога хранилища шрифта, изменение for f in ./*
к for f in /directory/containing/fonts/*
. Это - очень основанный на оболочке метод, настолько довольно медленный, и также нерекурсивно. Это только создаст каталоги, если будут файлы, которые запускаются с символа соответствия.
target=/directory/to/store/alphabet/dirs
mkdir "$target"
for f in ./* ; do
if [[ -f "$f" ]]; then
i=${f##*/}
i=${i:0:1}
dir=${i^}
if [[ $dir != [A-Z] ]]; then
mkdir -p "${target}/#" && mv "$f" "${target}/#"
else
mkdir -p "${target}/$dir" && mv "$f" "${target}/$dir"
fi
fi
done
Как один лайнер, снова из каталога хранилища шрифта:
target=/directory/to/store/alphabet/dirs; mkdir "$target" && for f in ./* ; do if [[ -f "$f" ]]; then i=${f##*/}; i=${i:0:1} ; dir=${i^} ; if [[ $dir != [A-Z] ]]; then mkdir -p "${target}/#" && mv "$f" "${target}/#"; else mkdir -p "${target}/$dir" && mv "$f" "${target}/$dir" ; fi ; fi ; done
использование метода А находит, с подобной обработкой строк, с помощью расширения параметра удара, которое будет рекурсивным, и должно быть несколько более быстрым, чем чистая версия оболочки:
find . -type f -exec bash -c 'target=/directory/to/store/alphabet/dirs ; mkdir -p "$target"; f="{}" ; i="${f##*/}"; i="${i:0:1}"; i=${i^}; if [[ $i = [[:alpha:]] ]]; then mkdir -p "${target}/$i" && mv "$f" "${target}/$i"; else mkdir -p "${target}/#" && mv "$f" "${target}/#"; fi' \;
Или больше четко:
find . -type f -exec bash -c 'target=/directory/to/store/alphabet/dirs
mkdir -p "$target"
f="{}"
i="${f##*/}"
i="${i:0:1}"
i=${i^}
if [[ $i = [[:alpha:]] ]]; then
mkdir -p "${target}/$i" && mv "$f" "${target}/$i"
else
mkdir -p "${target}/#" && mv "$f" "${target}/#"
fi' \;
Игравший в гольф кодом все же читаемый со всего двумя командами и двумя регулярными выражениями:
mkdir -p '#' {a..z}
prename -n 's|^[[:alpha:]]|\l$&/$&|; s|^[0-9]|#/$&|' [[:alnum:]]?*
Если у Вас есть огромная сумма файлов для перемещения, слишком многие для вписывания в список аргументов процесса (да, существует предел, и это могут быть всего несколько килобайтов), можно генерировать список файлов с другой командой и каналом это к prename
, например:
find -mindepth 1 -maxdepth 1 -name '[[:alnum:]]?*' -printf '%f\n' |
prename -n 's|^[[:alpha:]]|\l$&/$&|; s|^[0-9]|#/$&|'
Это обладает дополнительным преимуществом не попытки переместить литеральное имя файла [[:alnum:]]?*
если никакие файлы не соответствуют шаблону шарика. find
также позволяет намного больше критериев соответствия, чем оболочка globbing. Альтернатива должна установить nullglob
опция оболочки и близко стандартный входной поток prename
.1
В обоих случаях удалите -n
переключитесь, чтобы на самом деле переместить файлы и не просто показать, как они были бы перемещены.
Приложение: можно удалить пустые каталоги снова с:
rmdir --ignore-fail-on-non-empty '#' {a..z}
1 shopt -s nullglob; prename ... <&-