2016-03-31 3 views
6

Я знаю, что могу создать серию вложенных каталогов через довольно многословную серию mkdir -p с флагом -p, применяемым для подавления предупреждений о том, что каталог уже существует. Это становится очень многословным с отдельными вызовами, то есть:Создание иерархического дерева каталогов из представления компактных строк

mkdir -p hello 
mkdir -p hello/i_am_a 
mkdir -p hello/i_am_a/boy 
mkdir -p hello/i_am_a/girl 
mkdir -p hello/i_am_a/alien 
mkdir -p hello/i_am_a/dog 
mkdir -p hello/my_name_is 
mkdir -p hello/my_name_is/jim 
mkdir -p hello/my_name_is/bob 
mkdir -p hello/my_name_is/secret 

Я хотел бы, чтобы вместо того, чтобы построить дерево или, по крайней мере, часть в одном вызове с вложенной шаблон, состоящей из списка с раскрытием характера (т.е. {) , символ разделителя списка (то есть ,). и символ закрытия списка (т.е. }).

Для каждого уровня, начинающегося с вершины, каталог этого имени создается, если он еще не существует.

Чтобы продолжить свой глупый выше пример с реальными словами, я хотел бы использовать строку ввода:

«привет {i_am_a {мальчика, девочка, чужая, собака}, my_name_is {джим, боб, секрет}} '

... который должен создать следующие ...

hello 
hello/i_am_a 
hello/i_am_a/boy 
hello/i_am_a/girl 
hello/i_am_a/alien 
hello/i_am_a/dog 
hello/my_name_is 
hello/my_name_is/jim 
hello/my_name_is/bob 
hello/my_name_is/secret 

Для удобства, скажем, что если длина это влияет раствора, мы можем предположить, что нет более n слои гнездования в полученном дереве (например, n=3 в моем примере выше, например).

Предположим далее, для удобства, что три специальные структуры символов (в приведенном выше примере, например {, , и }) никогда не будет происходить во вложенных строк, то есть они никогда не будут отображаться в результате пути к файлам ,

Кажется, Perl или Python встроенный скрипт может сделать трюк, но, возможно, есть более простое решение с использованием встроенной функции BASH?

Моя цель - краткое решение, которое ограничивает многословие моих сценариев пост-обработки данных, которые часто связаны с созданием иерархических деревьев каталогов, заполненных на более глубоких уровнях промежуточными звеньями, которые я сохраняю для повторного использования и с законченными результатами в каталоги к вершине дерева.

+9

Вы были здесь достаточно долго, чтобы знать, что этот тип запроса «напишите мой код для меня» полностью не соответствует теме StackOverflow. Проверьте [ask] и посетите [help]. –

+0

Существует ряд высокоценных вопросов, требующих очень специфических однострочных. В этом случае я просто спрашиваю, как реализовать небольшое очень конкретное действие с неоднозначным методом. Это ничем не отличается от запроса «как мне заставить это регулярное выражение работать». Я не думаю, что вымогательство лаконичных/хорошо сделанных однострочных составляющих «напишите мой код», если сделать экономно ... –

+1

Посмотрите на решение Ф. Хаури! При всей вашей снисходительности был простой ответ, чтобы выполнить это! Кстати, это был похожий, но немного другой вопрос, и сообщество явно признало его приемлемым: http://stackoverflow.com/questions/2445213/building-a-directory-tree-from-a-list-of-file-paths Just потому что у ВАС нет конкретного решения для конкретного запроса, это не значит, что вы должны атаковать тех, кто публикует его, если цель ограничена и четко определена. Опять же, если бы мы применили ваш стандарт, возможно, 50% вопросов, связанных с сценарием, оцененных 2 или выше, исчезли бы ... –

ответ

19

Попробуйте это:

mkdir -p hello/{i_am_a/{boy,girl,alien,dog},my_name_is/{jim,bob,secret}} 

, кажется, делает работу:

find * 
hello 
hello/i_am_a 
hello/i_am_a/dog 
hello/i_am_a/alien 
hello/i_am_a/boy 
hello/i_am_a/girl 
hello/my_name_is 
hello/my_name_is/bob 
hello/my_name_is/secret 
hello/my_name_is/jim 

... дальше?

Это создаст 30 файлов (с именем file_0a к file_2j) в каждом из этих каталогов:

touch hello/{i_am_a/{boy,girl,alien,dog},my_name_is/{jim,bob,secret}}/file_{0..2}{a..j} 

(Для заполнения этих 210 файлов, вы можете заменить touch на date | tee, для образца.)

find * -ls | sed -ne '1,7{p;d};:;N;$!b;${s/^.*\(\(\n[^\n]*\)\{5\}\)\n*$/...\1/p;}' 
1703938 4 drwxr-xr-x 4 user user 4096 avr 3 22:23 hello 
1703939 4 drwxr-xr-x 6 user user 4096 avr 3 22:23 hello/i_am_a 
1703943 4 drwxr-xr-x 2 user user 4096 avr 3 22:23 hello/i_am_a/dog 
1704066 0 -rw-r--r-- 1 user user  0 avr 3 22:23 hello/i_am_a/dog/file_2i 
1704057 0 -rw-r--r-- 1 user user  0 avr 3 22:23 hello/i_am_a/dog/file_1j 
1704061 0 -rw-r--r-- 1 user user  0 avr 3 22:23 hello/i_am_a/dog/file_2d 
1704052 0 -rw-r--r-- 1 user user  0 avr 3 22:23 hello/i_am_a/dog/file_1e 
... 
1704076 0 -rw-r--r-- 1 user user  0 avr 3 22:23 hello/my_name_is/jim/file_0i 
1704097 0 -rw-r--r-- 1 user user  0 avr 3 22:23 hello/my_name_is/jim/file_2j 
1704074 0 -rw-r--r-- 1 user user  0 avr 3 22:23 hello/my_name_is/jim/file_0g 
1704073 0 -rw-r--r-- 1 user user  0 avr 3 22:23 hello/my_name_is/jim/file_0f 
1704081 0 -rw-r--r-- 1 user user  0 avr 3 22:23 hello/my_name_is/jim/file_1d 

...А так как Jonathan Leffler предлагаем, посмотрите на man -Pless\ +/Brace.Expansion bash

+0

Да, это потрясающе просто. :) Благодаря! –

+3

@ JasonR.Mick: см. Также [Расширение брекета] (https://www.gnu.org/software/bash/manual/bash.html#Brace-Expansion) в руководстве Bash; он включает пример, подобный этому. –

+1

Спасибо @JonathanLeffler, я пропустил мой * RTFM * рекомендация: 'man -Pless \ +/Brace.Expansion bash' –

Смежные вопросы