У меня есть веб-сервер Linux с примерно 25 000 изображений в одном каталоге. Все они в нижнем регистре и имеют формат из двух букв, трех цифр и jpg в качестве расширения. Поскольку управлять большим количеством файлов в одной папке становится сложно, я хочу переместить их во вложенные папки на основе первых двух букв имени файла, например:
/images/ab123.jpg --> /images/ab/ab123.jpg
/images/ab383.jpg --> /images/ab/ab383.jpg
/images/sk234.jpg --> /images/sk/sk234.jpg
Мне уже удалось перечислить всего около 250 различных комбинаций букв и создать подкаталоги:
ls | awk '{print substr($0,0,2)}' | uniq | xargs mkdir
Но мне не удается переместить файлы. Любые идеи?
Bash может извлечь подстроки за вас.
Вот однострочный текст, который предполагает, что целевые каталоги уже существуют:
cd /images; for f in *.jpg; do mv "$f" "${f:0:2}"; done
Этот небольшой скрипт создает каталоги за вас и выполняет действия.
cd /images &&
for f in *.jpg
do
pre=${f:0:2}
if [[ ! -d $pre ]]
then
mkdir "$pre"
fi
mv "$f" "$pre"
done
Многие файлы, поэтому давайте избегать подстановки в пользу find (1): И я использую Zsh как оболочку: остается проблема с именами файлов, содержащими двойные кавычки
find -maxdepth 1 -type f -exec zsh -c 'a="{}";b=${a:0:4}; mkdir -p $b; mv -t $b $a' \;
Попробуйте с
for i in $(find . -type f -maxdepth 1); do mv $i $(echo $i|awk '{print substr($0,0,2)}');done
Я считаю, что самый простой способ - использовать rename
команда с соответствующим регулярным выражением:
rename 's/^([a-zA-Z]{2})/$1\/$&/' *.jpg
Описание:
$& - its original filename,
$1 - matched 2 first letters, used here as directory name