Итак, с bash
расширением алфавита, это работает:
set {a..z}
for a do printf "./$a/$a%s\n" "$@"
done | xargs mkdir -p
И если вы просто набираете алфавит один раз в первой строке, то такая же концепция должна переноситься на любую оболочку. Есть и другие способы добраться до заданной строки, если вы не хотите печатать ее так:
seq -sP32P 97 123|dc
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
... например, работает в ASCII локали. Таким образом, вы можете выполнить set $(seq -sP32P 97 123|dc)
или любую другую команду, которая выдаст вам $IFS
отдельный список аргументов, которые вам нужны, но, я имею в виду, вероятно, лучше просто использовать bash
вещь или набрать ее.
Во всяком случае, я думаю, что я бы так поступил, хотя бы потому, что он вызывается mkdir
так часто, как это необходимо.
И просто чтобы продемонстрировать, как это работает, вот небольшой отладочный вывод меньшего набора:
sh -cx 'for n do printf "./$n/$n%s\n" "$@"; done|cat' -- arg1 arg2 arg3
+ for n in '"$@"'
+ printf './arg1/arg1%s\n' arg1 arg2 arg3
+ cat
+ for n in '"$@"'
+ printf './arg2/arg2%s\n' arg1 arg2 arg3
+ for n in '"$@"'
+ printf './arg3/arg3%s\n' arg1 arg2 arg3
./arg1/arg1arg1
./arg1/arg1arg2
./arg1/arg1arg3
./arg2/arg2arg1
./arg2/arg2arg2
./arg2/arg2arg3
./arg3/arg3arg1
./arg3/arg3arg2
./arg3/arg3arg3
Как вы можете видеть, for
единственные циклы один раз на индекс массива позиционных параметров, которые я здесь устанавливаю, просто передавая sh
параметры при вызове и выше с помощью set ${positionals}
. Но printf
получает один и тот же массив в своем списке аргументов для каждой итерации и применяет свою строку формата к каждому из своих аргументов, так что вы получаете видимость рекурсии без какой-либо ненужной рекурсии.
А добавление done|command
воли к потоку всех for
выходных данных цикла по каналу таким же образом done >file
приведет к тому, что все это будет передано в файл - только один раз открывая и закрывая выходной файл для всей for...done
конструкции.