
У меня есть куча папок, и я хочу пройтись по всем этим папкам и в каждой папке создать еще одну папку с названием «Фото».
F1
--F11
----F111
----F112
--F12
Я хочу иметь:
F1
--Photo
--F11
----Photo
----F111
------Photo
----F112
------Photo
--F12
----Photo
решение1
Этого можно добиться с помощью одного find
звонка.
find . -name 'Photo' -prune -o -type d -exec mkdir {}/Photo \;
Часть -name 'Photo' -prune -o
говорит не возвращаться к существующим (и вновь созданным) Photo
каталогам: Если найденный файл (или каталог) имеет имя Photo
, прекратить его обработку ( -prune
). В противном случае ( -o
) продолжить с каталогами ( -type d
) и выполнить ( -exec
) команду.
решение2
Вы можете передать 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 за помощь в этом вопросе :)
решение3
Из каталога, расположенного чуть выше 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
верхний. - Добавлена поддержка нестандартных имен файлов (по предложениям Тердона).
решение4
Если вы используете 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
подкаталога в целевом каталоге, содержащемфайлпод названием Фото. Вы не указали, что следует делать в таких случаях, и все остальные ответы, опубликованные до сих пор, также имеют это ограничение.