Рекурсивно створюйте папку "Фото" у всіх каталогах


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 , він може провалюватися незвичними способами. Я думаю, що відповіді, які цього уникають, напевно, безпечніші.
Арронічний

3
@Arronical lsне розбирається. Це просто відгук для користувача ... показує, що відбувається. Як і слова "Це каталог фотографій". Це дозволяє користувачеві знати, чому він не створює там каталог.
LD James

1
Я думав, що це може бути так, тому що я не бачив нічого з цим робити. У такому разі я відкликаю свій коментар і
відхиляюся

find -type d F1, можливо?
Олів'є Грегоар

Зауважте, що це не вдасться, якщо є файл (а не каталог) $i/Photo, але ОП не вказав, що робити в такому випадку. Він також вийде з ладу у, мабуть, малоймовірному випадку, коли один із $is містить новий рядок.
тердон

24

Ви можете досягти цього за допомогою одного findдзвінка.

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

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


ах приємно, я спробував це саме так, і з вашої відповіді я бачу, де я пішов не так :)
Zanna

@Zanna -prune? :) Так, це досить контр-інтуїтивно, але варто вчитися.
Мелебій

Чи перестане створювати папку "Фото", якщо існує файл з назвою "Фото"?
Анвар

3
@Anwar Поточна версія буде. У вимогах є сіра зона. :) Ви можете змінити це, вказавши -type dразом із -name 'Photo'раніше -prune.
Мелебій

2
@Anwar На другий погляд це не має сенсу. Не можна створити папку з тим самим іменем, що і звичайний файл, в одній папці. І findбуде продовжено з іншими папками (включаючи вкладені папки цієї папки, якщо ви цього вимагаєте).
Мелебій

9

Ви можете передавати 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 за допомогу в цьому :)


Якщо F1довідник ОП є ~user/Pictures, переміщення до батьківського каталогу та запуску рядка помістить Photoу кожен каталог у своєму просторі каталог, якого може бути тисячі. Розгляньте додавання F1як частину комерційної лінії, щоб уникнути легко зробленої помилки. Таким чином, якщо він ненавмисно запускається з неправильного місця, він не створюватиме каталоги.
ЛД Джеймс

ах так, я насправді не знав їх структури каталогів. Я пропоную зробити це F1замість цього, редагував @LDJames
Zanna

5

Python with 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" разом, щоб утворити один шлях

Замініть "/ Картинки" на "/ Фото", щоб відповідати вашим вимогам


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.