Создать папку «Фото» внутри всех каталогов рекурсивно


9

У меня есть несколько папок, и я хочу перебрать все эти папки и в каждой папке создать другую папку с именем «Фото»

F1
--F11
----F111
----F112
--F12

Я хочу иметь:

F1
--Photo
--F11
----Photo
----F111
------Photo
----F112
------Photo
--F12
----Photo

Ответы:


8

Из каталога чуть выше 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).

1
Я бы определенно избегал парсинга ls , он может потерпеть неудачу необычным образом. Я думаю, что ответы, которые избегают этого, вероятно, более безопасны.
Arronical

3
@ Arronical lsне анализируется. Это просто обратная связь с пользователем ... показывающая, что происходит. Так же, как слова "Это каталог фотографий". Он сообщает пользователю, почему он не создает каталог там.
Л.Д. Джеймс

1
Я думал, что это может быть так, поскольку я не мог видеть, что с этим что-то делается. В этом случае я убираю свой комментарий и
отклоняюсь

find -type d F1, может быть?
Оливье Грегуар,

Обратите внимание, что это не удастся, если будет вызван файл (а не каталог) $i/Photo, но в OP не указано, что следует делать в таком случае. Это также потерпит неудачу в, по общему признанию маловероятном случае, когда один из $is содержит символ новой строки.
Тердон

24

Вы можете достичь этого с помощью одного findзвонка.

find . -name 'Photo' -prune -o -type d -exec mkdir {}/Photo \;

Часть -name 'Photo' -prune -oговорит не возвращаться к существующим (и вновь созданным) Photoкаталогам: если найденный файл (или каталог) имеет имя Photo, прекратите его обработку ( -prune). В другом случае ( -o) продолжайте с directoryies ( -type d) и execute ( -exec) командой.


Ах, хорошо, я попробовал это таким образом, и я вижу из твоего ответа, где я ошибался :)
Zanna

@ Занна -prune? :) Да, это довольно нелогично, но стоит учиться.
Мелебиус

Прекратится ли создание папки «Фото», если существует файл с именем «Фото»?
Анвар

3
@Anwar Текущая версия будет. В требованиях есть серая зона. :) Вы можете изменить это, указав -type dвместе с -name 'Photo'before -prune.
Мелебиус

2
@ Анвар На второй взгляд, это не имеет смысла. Вы не можете создать папку с тем же именем, что и обычный файл в той же папке. И findпродолжит работу с другими папками (включая подпапки этой папки, если вы об этом просите).
Мелебиус

9

Вы можете передать 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 за помощь в этом :)


Если F1каталог операции есть ~user/Pictures, перемещение в родительский каталог и запуск строки поместит Photoкаталог в каждый каталог в его пространстве, который может быть тысяч. Подумайте о добавлении в F1качестве части commanline, чтобы избежать легко допущенной ошибки. Таким образом, если он случайно запущен не из того места, он не будет создавать каталоги.
Л.Д. Джеймс,

ах да, я на самом деле не был уверен в их структуре каталогов. F1Вместо этого я предлагаю сделать это отредактировано @LDJames
Zanna

5

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", чтобы соответствовать вашим требованиям


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подкаталог в целевом каталоге, который содержит файл с именем Photo. Вы не указали, что следует делать в этих случаях, и все остальные ответы, опубликованные до сих пор, также имеют это ограничение.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.