Создайте папку “ Photo ” внутри всех каталогов рекурсивно

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

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

Я хочу иметь:

F1
--Photo
--F11
----Photo
----F111
------Photo
----F112
------Photo
--F12
----Photo
1
задан 14 September 2016 в 12:23

4 ответа

Вы можете достичь этого, используя один вызов find.

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

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

24
ответ дан 23 May 2018 в 06:10
  • 1
    хорошо, я пробовал это так, и я вижу из вашего ответа, где я ошибся :) – Zanna 14 September 2016 в 12:16
  • 2
    @Zanna -prune? :) Да, это довольно противоречиво, но стоит учиться. – Melebius 14 September 2016 в 12:22
  • 3
    Не прекратит ли создание папки «Фото», если существует файл с именем «Фото»? – Anwar 14 September 2016 в 12:40
  • 4
    @Anwar Текущая версия будет. В требованиях есть серая зона. :) Вы можете изменить это, указав -type d вместе с -name 'Photo' до -prune. – Melebius 14 September 2016 в 12:43
  • 5
    @Anwar На втором взгляде это не имеет смысла. Вы не можете создать папку с тем же именем, что и обычный файл в той же папке. И find будет продолжаться с другими папками (включая вложенные папки этой папки, если вы просите об этом). – Melebius 14 September 2016 в 13:31

Вы можете передать результаты find в while вместо for, так как это не будет прерываться, если имена файлов имеют пробелы

Сначала cd в каталог 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 за помощь в этом:)

9
ответ дан 23 May 2018 в 06:10
  • 1
    Если каталог op F1 - ~user/Pictures, переход в родительский каталог и запуск строки поместит каталог Photo в каждый каталог в его пространстве, который может быть тысячами. Подумайте о том, чтобы добавить F1 в качестве части commanline, чтобы избежать легко сделанной ошибки. Таким образом, если он непреднамеренно работает из-за неправильного места, он не будет создавать каталоги. – L. D. James 14 September 2016 в 15:18
  • 2
    Ах, да, я действительно был не уверен в их структуре каталогов. Я предлагаю сделать это из F1 вместо этого, отредактировал @ L.D.James – Zanna 14 September 2016 в 15:23

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 с [ f3], чтобы указать команду, которую мы даем в одинарных кавычках. Функция os.walk() позволяет нам рекурсивно проходить через все подкаталоги, и для каждого подкаталога (представленного r) мы создаем папку «Изображения» через функцию os.mkdir(). r+"/Pictures" - просто простая манипуляция с строкой, чтобы соединить строку подкаталога и строку «/ Pictures» вместе, чтобы сформировать один путь

Заменить «/ Pictures» на «/ Photo» в соответствии с вашими требованиями

5
ответ дан 23 May 2018 в 06:10

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

5
ответ дан 23 May 2018 в 06:10

Другие вопросы по тегам:

Похожие вопросы: