Створення численних каталогів за допомогою mkdir


14

Я хотів би створити багато каталогів, використовуючи mkdir. Кожне ім'я каталогу буде складатися з префікса (рядок) та індексу (ціле число). Припустимо, я хотів би, щоб префікс був "s", а індекси були від 1 до 50. Це означає, що я хотів би створити каталоги під назвою:

s1,, s2... s49,,s50

Чи є спосіб зробити це автоматично, використовуючи mkdir? Дякую за ваш час.


2
Яку оболонку ви використовуєте?
Франческо Турко

@FrancescoTurco я використовую bash. Спасибі за ваш час!
Андрій

3
FYI, я вважаю , що набагато корисніше використовувати равношірінние індекси, як: s01, s02, ..., s49, s50. Якщо я використовував показники фіксованої ширини, /bin/lsмайже завжди створює потрібне мені замовлення.
Роб

Відповіді:


32

Це можна зробити за допомогою сценарію оболонки.

Чистий ш - це працюватиме навіть на попередніх POSIX-оболонках:

n=1;
max=50;
while [ "$n" -le "$max" ]; do
  mkdir "s$n"
  n=`expr "$n" + 1`;
done

Якщо ви хочете створити велику кількість каталогів, ви можете зробити сценарій швидше, зменшивши його до одного виклику mkdir, а також використовуючи вбудовані оболонки для тестування та арифметики. Подобається це:

n=1
max=50
set -- # this sets $@ [the argv array] to an empty list.

while [ "$n" -le "$max" ]; do
    set -- "$@" "s$n" # this adds s$n to the end of $@
    n=$(( $n + 1 ));
done 

mkdir "$@"

Zsh, ksh93 або bash роблять це набагато простіше, але я повинен зазначити, що це не вбудовано mkdirі може не працювати в інших оболонках. У більших випадках на це можуть впливати також обмеження кількості або загального розміру аргументів, які можуть бути передані команді.

mkdir s{1..50}

3
+1 Це чудово! Мені все одно до речі, але n=$(( n + 1 ))це було б так само POSIX і не коштував би вам передплати.
kojiro

@rahmu [[ключове слово не є POSIX. (Не кажучи вже про те, що [ це оболонка, вбудована у багато сучасних снарядів.)
kojiro

@kojiro: [[працює на моєму ksh88(який раніше bash), тому я припустив, що це POSIX. Я не зміг знайти жодної згадки про неї в специфікації POSIX, тому я вважаю, що ти маєш рацію. Дякую за інформацію!
rahmu

Я думав над тим, щоб додати версію за допомогою арифметичного розширення, але хотів обмежити "чистий ш" тим, що працювало б і перед версіями POSIX. Я також не згадував seq з тієї ж причини - якщо у вас є seq, ви, ймовірно, маєте баш. Приклад циклу також хороший для обходу обмежень аргументів для більшої кількості каталогів, що також означає, що є місце for i in {range}для користувачів розширених оболонок.
Випадково832

Підказка zsh в кінці дивовижна, це заощадило мені стільки часу!
Jase

33
  • Один

    for i in {1..50}; do
      mkdir s"$i"
    done
  • Два

    mkdir s{1..50}

    Цей параметр працює у bash , zsh та ksh93

  • Три

    mkdir $(printf "s%02i " $(seq 1 50))

4
Навіщо ти коли-небудь використовувати один понад два?
Кевін

7
ви можете зробити більше, $iніж просто створити каталог, наприклад mkdir s$i ; echo $i > s$i/$i. Крім того, один є приємним, простим прикладом використання циклу в bash ... на такому веб-сайті початківці користувачі навряд чи можуть це побачити і подумати "добре, я не розумів, що ти можеш це зробити" "---> просвітлення.
cas

1
@rahmu Це функція, знайдена в Bash / Zsh (ймовірно, також ksh93). Не потрібно брати участь у голосуванні.
helpermethod

3
@rahmu: Я думаю, що варто задуматися лише у тому випадку, якщо відповідь jhonathan виправить проблему з оболонкою OP (bash), не обов'язково з іншими.
Франческо Турко

4
@Kevin, хоча це не буде проблемою для п’ятдесяти, якщо у вас є п’ятсот каталогів, щоб змусити вас турбуватися про обмеження аргументів.
Випадково832

10

Тут багато складних відповідей, але баш робить це дуже просто. Звичайно, чисте рішення POSIX працює, але чому б не скористатися bashоболонкою, якою ви користуєтесь? Це можна легко зробити за допомогою розширення дужок :

% mkdir -v s{1..10} && ls -1d s{1..10}                                   (09-24 17:37)
mkdir: created directory `s1'
mkdir: created directory `s2'
mkdir: created directory `s3'
mkdir: created directory `s4'
mkdir: created directory `s5'
mkdir: created directory `s6'
mkdir: created directory `s7'
mkdir: created directory `s8'
mkdir: created directory `s9'
mkdir: created directory `s10'
s1
s10
s2
s3
s4
s5
s6
s7
s8
s9

5

mkdir $(seq --format 's%.0f' 1 50)

або якщо вам потрібні нульові цифри (що було б краще для сортування):

mkdir $(seq --format 's%02.0f' 1 50)

або:

mkdir s$(seq -s ' s' -w 1 50)- відзначте рядок 's' безпосередньо перед $(), без нього першою створеною каталогом буде просто '01', а не 's01'

і, нарешті: mkdir $(printf "s%02i " $(seq 1 50))

seq походить від GNU Coreutils

як не дивно, seq --formatабо -fпараметр дозволяє лише подвійні типи плаваючої точки printf (наприклад, f і g. також дивний шістнадцятковий формат з плаваючою точкою, для якого я жодного разу не знайшов). Я поняття не маю, чому. Було б добре, якби він підтримував також інші printf(3)числові типи, такі як цілі (d, i), восьмеричні (o, U) або шістнадцяткові (x, X).

У будь-якому випадку, для цієї мети подвійний формат з точністю до 0 десятків подобається %.0fчи %02.0fдостатньо близький до цілого числа.

$ seq - допомогти
Використання: seq [ОПЦІЯ] ... ОСТАННІ
  або: seq [ОПЦІЯ] ... ПЕРШИЙ ПОСЛІД
  або: послідовно [ОПЦІЯ] ... ПЕРШИЙ ІНФОРМАЦІЇ ОСТАННІ
Роздрукуйте номери від ПЕРШОГО до ОСТАНОГО, кроки ВПРОВАДЖЕННЯ.

  -f, --format = FORMAT використовувати FORMAT з плаваючою точкою в стилі printf
  -s, --separator = STRING використовувати STRING для розділення чисел (за замовчуванням: \ n)
  -w, - рівна ширина вирівнюється по ширині шляхом прокладки з провідними нулями
      - допоможіть відобразити цю допомогу та вийти
      - інформація про вихідну версію та вихід

Якщо ПЕРШИЙ або ВПРАВЛЕННЯ пропущено, він за замовчуванням дорівнює 1. Тобто, an
опущені значення INCREMENT до 1, навіть коли LAST менше ПЕРШОГО.
ПЕРШИЙ, ВПРОВАДЖЕННЯ та ОСТАННІ інтерпретуються як значення з плаваючою комою.
ВПРОВАДЖЕННЯ зазвичай є позитивним, якщо ПЕРШИЙ менший за ОСТАННІ та
ВПРАВЛЕННЯ зазвичай є негативним, якщо ПЕРШИЙ більший за ОСТАННУЮ.
FORMAT повинен бути придатним для друку одного аргументу типу `double ';
він за замовчуванням до% .PRECf, якщо FIRST, INCREMENT та LAST - всі фіксовані точки
десяткові числа з максимальною точністю PREC, а до% g в іншому випадку.

Дивіться також: http://www.gnu.org/software/coreutils/manual/html_node/seq-invocation.html


{1,50}або {01,50}(для нульового прокладки) набагато простіше і зрозуміліше.
Кевін

1
правда ... якщо ви використовуєте bash, а не sh. ось чому я підтримав відповідь @ Random832. це гарна відповідь. використання seq - це також корисна відповідь.
cas

4

Щоб бути іншим, ось рішення POSIX sh, яке використовує рекурсію:

makedirs() {
  [ "$1" -gt 0 ] || return
  mkdir "s$1"
  makedirs $(( $1 - 1 ))
}
$ makedirs 9
$ ls
s1  s2  s3  s4  s5  s6  s7  s8  s9
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.