Автоматизированный способ создания дерева каталогов

11

Я пытаюсь сделать дерево каталогов от А до Я, где следующий каталог находится в текущем каталоге.

Например: B находится внутри A, а C находится внутри B и так далее.

-A
--B
---C
----...Z

Любые подсказки о том, как сделать это автоматизированным способом?

Ниша
источник
Интересно, какова практическая цель таких каталогов. ИМХО, это больше похоже на вопрос для Code Golf .
Мелебиус
3
@Melebius Одной из возможных целей является создание структуры каталогов в качестве контрольного примера, чтобы помочь проверить, работает ли какое-либо другое свойство команды, сценария или приложения. Вот недавний случай, когда сам вопрос был не о создании определенных структур каталогов, но знание того, как писать команды для этого, было полезно для целей тестирования, не несмотря на то, что конкретная структура была придумана и странна, а из-за этого. (У нас также есть много вопросов о создании определенных структур каталогов, которые можно найти, выполнив поиск " mkdir -p".)
Элия ​​Каган

Ответы:

25

С mkdir, printfи расширение скобки Bash:

$ mkdir -p "$(printf "%s/" {A..Z})"
$ tree A
A
└── B
    └── C
        └── D
            └── E
                └── F
                    └── G
                        └── H
                            └── I
                                └── J
                                    └── K
                                        └── L
                                            └── M
                                                └── N
                                                    └── O
                                                        └── P
                                                            └── Q
                                                                └── R
                                                                    └── S
                                                                        └── T
                                                                            └── U
                                                                                └── V
                                                                                    └── W
                                                                                        └── X
                                                                                            └── Y
                                                                                                └── Z

25 directories, 0 files
  • {A..Z}расширяется до A B ... Z,
  • printf "%s/"выводит аргументы /после них, поэтому я получаюA/B/...Z/
  • и mkdir -pсоздает A/B/.../Zкаталог со всеми родительскими каталогами, которые необходимо было создать.
Мур
источник
Спасибо за это. Думал, пока получаю эту ошибку. Я использую команду MKDIR: A / B / C / D / E / F / G / H / I / J / K / L / M / N / O / P / Q / R / S / T / U / V / W / X / Y: Нет такого файла или директории
Nish
3
@Nish Есть -pв mkdirкоманде.
Муру
мой плохой, я попробовал это на своем Mac вместо Ubuntu. И следующий вопрос заключается в следующем -> скажем, я хотел иметь каталог A1..A100 внутри A (в той же структуре AtoZ). Тогда B1..B100 в B. Так это выглядит примерно так -> imgur.com/jfuKEdf
Nish
11
Допустим, вы публикуете продолжение как реальный вопрос, а не в комментариях, и используете не изображения, а текст. Это было бы намного лучше, нет?
Муру
Я понимаю вашу точку зрения здесь. Его сложно опубликовать, так как это не код, а огромный вывод. Так что простой взгляд на скриншот облегчает понимание.
Nish
7

На очень простом уровне вы можете использовать {A..Z}расширение, чтобы сгенерировать все буквы, а затем итеративно создать и ввести каждое из них:

~/test_directory$ for d in {A..Z}; do mkdir "$d"; cd "$d"; done
~/test_directory/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z$ 

Как вы можете видеть в выводе моей подсказки, теперь у вас есть полностью сцепленный каталог.

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

while IFS= read -r dir_name;do mkdir "$dir_name"; cd "$dir_name" ;done < directory_list.txt
Сергей Колодяжный
источник
это круто. Вот дополнительный вопрос. скажем, я хотел иметь каталог A1..A100 в пределах A (в той же структуре AtoZ). Тогда B1..B100 в B. Так это выглядит примерно так -> imgur.com/jfuKEdf
Nish
@ Ниш, ну, для этого нужен внутренний цикл, такfor d in {A..Z}; do mkdir "$d"; cd "$d"; for i in {1..100}; do mkdir "${d}${i}" ;done ; done
Сергей Колодяжный
Или даже без внутреннего цикла,for d in {A..Z}; do mkdir "$d"; cd "$d"; mkdir "$d"{1..100}; done
Сергей Колодяжный
Спасибо за это. Кажется, что это работает, но порядок каталога, кажется, облажался, поэтому 2 не после 1. Он отсортирован случайным образом. В любом случае, чтобы это исправить? Вот скриншот -> imgur.com/a/Zqj1c
Ниш
Порядок сортировки @Nish основывается на тексте, а не на цифрах, как я думаю, вы ожидаете. Насколько treeя не уверен, как это исправить, но я думаю, что это может быть даже не treeпроблемой, а порядком сортировки оболочки. Я бы предложил задать актуальный вопрос об этом либо здесь, либо еще лучше на unix.stackexchange.com
Сергей Колодяжный,
2

Хотя путь Муру неprintf может быть побежден , мне лично нравятся jotтакие вещи. jotне устанавливается по умолчанию в Ubuntu. athena-jotПакет обеспечивает его. Любая из этих команд работает:

mkdir -p "$(jot -s/ -c 26 A)"
jot -s/ -c 26 A | xargs mkdir -p

Действительно любая команда, которая генерирует последовательность букв и соединяет их с косой чертой, облегчит это, потому что ее вывод может быть передан mkdir -pлибо путем подстановки команды (как в ответе Муру ), либо с помощью xargs. Вот несколько примеров использования нескольких инструментов, xargsкоторые не требуют установки программного обеспечения, за исключением, возможно, очень минимальных систем или Ubuntu Core:

perl -we 'print join "/", A..Z' | xargs mkdir -p
ruby -we 'print (?A..?Z).to_a * ?/' | xargs mkdir -p
python3 -c 'print("/".join(__import__("string").ascii_uppercase))' | xargs mkdir -p

Старые выпуски Ubuntu поставляются с Python 2 вместо Python 3. Для этого просто измените python3на, pythonчтобы последняя команда работала, если вы действительно хотите сделать это с Python.

Точно так же короткий и простой способ Муру может быть записан так:

printf '%s/' {A..Z} | xargs mkdir -p

Замыкающий /путь в пути к каталогу mkdir -pпредлагается создать, это не проблема и, возможно, стилистически предпочтительнее. Но это прекрасно, если опустить другие примеры в этом ответе.

Элия ​​Каган
источник