Создать папку "Фото" внутри всех каталогов рекурсивно
У меня есть несколько папок, и я хочу перебрать все эти папки и в каждой папке создать другую папку с именем "Фото"
F1
--F11
----F111
----F112
--F12
Я хочу иметь:
F1
--Photo
--F11
----Photo
----F111
------Photo
----F112
------Photo
--F12
----Photo
5 ответов
Из каталога чуть выше F1 запустите этот скрипт:
Цель сценария - избежать создания избыточных фото-каталогов в фото-каталогах.
Кроме того, он предназначен для предотвращения случайного запуска его из неправильного места, такого как корневой каталог пользователя, тогда как он не увидит F1
каталог и по ошибке создать сотни фото-каталогов в неправильных дворцах.
Кроме того, я намеревался создать простой в использовании скрипт, чтобы пользователь мог его настроить.
#!/bin/bash
while IFS= read -r -d '' i;
do
if [[ ! -d $i/Photo ]]; then
# Filter to skip folders named Photo
thisfolder="$(echo $i | sed "s/.*\///")"
if [[ ! $thisfolder == "Photo" ]]; then
mkdir "$i/Photo"
fi
fi
done < <(find F1 -type d -print0)
Скрипт обновлен:
- Поменял нижний регистр
p
вphoto
в верхний регистр. - Добавлена поддержка нестандартных имен файлов (с предложениями от Terdon).
Вы можете достичь этого с помощью одного find
вызов.
find . -name 'Photo' -prune -o -type d -exec mkdir {}/Photo \;
Часть -name 'Photo' -prune -o
говорит не возвращаться к существующим (и вновь созданным) Photo
каталоги: если найденный файл (или каталог) имеет имя Photo
перестань его обрабатывать (-prune
). В другом случае (-o
), продолжить с каталогами (-type d
) и выполнить (-exec
) команда.
Вы могли бы пройти find
результаты к while
вместо for
так как это не сломается, если в именах файлов есть пробелы
Первый компакт-диск в каталог F1
затем выполните:
find -type d | while read dir ; do mkdir "$dir"/Photo ; done
Если каталог существует, mkdir
просто откажусь от его создания, так что никаких проблем нет...
Если имена ваших каталогов могут содержать переводы строк или другую странную странность, используйте это, которое может иметь дело с произвольными именами:
find -type d -print0 | while IFS= read -r -d '' dir ; do mkdir "$dir"/Photo ; done
Спасибо @terdon за помощь в этом:)
Python с os.walk
может сделать это довольно легко и всего за несколько строк кода
$ mkdir dir_one dir_two
$ mkdir dir_two/dir_three
$ python -c 'import os;[os.mkdir(r + "/Pictures") for r,d,f in os.walk(".")]'
$ tree
.
├── dir_one
│ └── Pictures
├── dir_two
│ ├── dir_three
│ │ └── Pictures
│ └── Pictures
└── Pictures
объяснение
Мы имеем дело с этой командой: python -c 'import os;[os.mkdir(r + "/Pictures") для r,d,f в os.walk(".")]'
Здесь мы просто вызываем Python интерпретатор с -c
флаг для указания команды, которую мы даем в одинарных кавычках. os.walk()
Функция позволяет нам рекурсивно шагать по всем подкаталогам и для каждого подкаталога (представленного r
), создаем папку Pictures через os.mkdir()
функция. r+"/Pictures"
это просто простое манипулирование строкой для объединения строки подкаталога и строки "/ Pictures" в один путь
Замените "/ Pictures" на "/Photo", чтобы соответствовать вашим требованиям
Если вы используете bash, вы можете просто запустить:
shopt -s globstar
for d in **/; do mkdir -p "$d"/Photo; done
globstar
вариант делает **
соответствует "все файлы и 0 или более каталогов и подкаталогов". Другими словами, это соответствует всему рекурсивно. Из-за /
в конце, **/
будет соответствовать всем каталогам и подкаталогам (без файлов). Следовательно $d
будет перебирать все каталоги в текущем каталоге и их подкаталогах и Photos
Каталог будет создан в каждом из них.
-p
флаг mkdir
средства:
-p, --parents
no error if existing, make parent directories as needed
Здесь я просто использую его для подавления сообщений об ошибках, если целевой каталог уже существует. Удалите его, если хотите увидеть ошибки.
Обратите внимание, что это не сможет создать Photo
подкаталог в целевом каталоге, который содержит файл с именем Photo. Вы не указали, что следует делать в этих случаях, и все остальные ответы, опубликованные до сих пор, также имеют это ограничение.