У меня есть файловая система, которую я хотел бы организовать в алфавитном порядке. Это является большим, и сделать это вручную заняло бы время жизни.
То, что я хотел бы знать, - было ли возможно записать что-то в терминале, который создаст папки A-Z и затем иметь терминал, ищут всю файловую систему и перемещают все подпапки в их соответствующую папку букв.
Я также хотел бы, чтобы поиск организовал основанный на расширении файла, найденном в подпапке.
например, найдите и переместите все подпапки, начинающиеся с буквы содержание расширения файла .doc к folderA.
Заранее спасибо
Можно использовать find
команда ниже к рекурсивно перемещению (в глубину) все папки в папку, названную в честь первой буквы их имени файла, создавая его, если это еще не существует, начинающий с Вашего текущего рабочего каталога:
find . -depth -mindepth 1 -type d -execdir bash -c 'l=./$(basename "{}" | head -c1) ; test -d "${l^^}" || mkdir "${l^^}" ; mv "{}" "${l^^}/"' \;
Объяснение:
find . -depth -mindepth 1 -type d -execdir <COMMAND> \;
.
), в глубину (-depth
), для всех каталогов (-type d
), исключая Ваш текущий каталог сам (-mindepth 1
).cd
s в родительский каталог каждой найденной папки и выполняется <COMMAND>
оттуда, заменяя каждое возникновение {}
с родственником нашел имя каталога (-execdir
).bash -c '<COMMAND>'
<COMMAND>
. Нам нужно это, потому что мы собираемся использовать функции оболочки как переменные, каналы, замена команды, и т.д., который не может быть сделан непосредственно find -execdir
.l=./$(basename "{}" | head -c1)
{}
заменен с результатом поиска) в переменной оболочки $l
.test -d "${l^^}" || mkdir "${l^^}"
проверки, существует ли каталог и создает его если нет. Название каталога ("${l^^}"
) содержание переменной $l
(первая буква найденного имени каталога) преобразованный в верхний регистр.
mv "{}" "${l^^}/"
перемещается найденный каталог (помните снова это {}
заменен) в каталог, названный после того, как его первая буква преобразовала в верхний регистр ('" $ {l^^} / ", который мы подготовили ранее).
Пример выполняется:
$ tree -F
.
├── apple/
│ ├── hamster/
│ ├── horse/
│ ├── snake/
│ │ ├── blue
│ │ ├── green
│ │ ├── grey
│ │ └── red
│ └── spider/
├── apricot/
├── banana/
├── cherry/
│ ├── pink
│ ├── purple
│ └── yellow
└── coconut/
9 directories, 7 files
$ find . -depth -mindepth 1 -type d -execdir bash -c 'l=./$(basename "{}" | head -c1) ; test -d "${l^^}" || mkdir "${l^^}" ; mv "{}" "${l^^}/"' \;
$ tree -F
.
├── A/
│ ├── apple/
│ │ ├── H/
│ │ │ ├── hamster/
│ │ │ └── horse/
│ │ └── S/
│ │ ├── snake/
│ │ │ ├── blue
│ │ │ ├── green
│ │ │ ├── grey
│ │ │ └── red
│ │ └── spider/
│ └── apricot/
├── B/
│ └── banana/
└── C/
├── cherry/
│ ├── pink
│ ├── purple
│ └── yellow
└── coconut/
14 directories, 7 files
Править:
Если Вы хотите это нерекурсивно, т.е. работа только на прямых подкаталогах первого уровня Вашего текущего рабочего каталога, просто добавьте -maxdepth 1
опция к find
команда. Можно опустить -depth
опция затем, хотя:
find . -mindepth 1 -maxdepth 1 -type d -execdir bash -c 'l=./$(basename "{}" | head -c1) ; test -d "${l^^}" || mkdir "${l^^}" ; mv "{}" "${l^^}/"' \;
Редактирование 2:
Возможно только выполнить перемещение, если каталог для перемещения содержит файлы, соответствующие определенному критерию (здесь: содержите файл с именем файла, заканчивающимся в .jpg
где угодно, включая подкаталоги), но это добавляет другого find
команда и if
пункт:
find . -depth -mindepth 1 -maxdepth 1 -type d -execdir bash -c 'if find "{}" -type f -iname '*.jpg' | grep -q '.' ; then l=./$(basename "{}" | head -c1) ; test -d "${l^^}" || mkdir "${l^^}" ; mv "{}" "${l^^}/" ; fi' \;
Объяснение (после того, как редактируют 2):
if <CONDITION> ; then <COMMANDS> ; fi
<CONDITION>
и только выполнения <COMMANDS>
между then
и fi
если условие было выполнено (код выхода 0). <COMMANDS>
совпадает с в предыдущей версии.find "{}" -type f -iname '*.jpg' | grep -q '.'
Поиски в каталоге найдены внешним find
команда (помнят еще раз это {}
заменен) файлы (-type f
) с именем, которое заканчивается .jpg
, нечувствительно к регистру (-iname '*.jpg'
).grep -q '.'
просто проверки, ли find
производит любой вывод на STDOUT (означает, что файлы были найдены), и возвращает код выхода 0 затем, 1, если никакие файлы не были найдены.Пример работает (после того, как отредактируйте 2):
$ tree -F
.
├── apple/
│ ├── hamster/
│ ├── horse/
│ ├── snake/
│ │ ├── blue
│ │ ├── green
│ │ ├── grey
│ │ └── red
│ └── spider/
├── apricot/
├── banana/
│ └── black.jpg
├── cherry/
│ ├── pink
│ ├── purple
│ └── yellow
└── coconut/
9 directories, 8 files
$ find . -depth -mindepth 1 -maxdepth 1 -type d -execdir bash -c 'if find "{}" -type f -iname '*.jpg' | grep -q '.' ; then l=./$(basename "{}" | head -c1) ; test -d "${l^^}" || mkdir "${l^^}" ; mv "{}" "${l^^}/" ; fi' \;
$ tree -F
.
├── A/
│ └── apple/
│ ├── hamster/
│ ├── horse/
│ │ └── white.jpg
│ ├── snake/
│ │ ├── blue
│ │ ├── green
│ │ ├── grey
│ │ └── red
│ └── spider/
├── apricot/
├── B/
│ └── banana/
│ └── black.jpg
├── cherry/
│ ├── pink
│ ├── purple
│ └── yellow
└── coconut/
11 directories, 9 files