Создание многочисленных каталогов с помощью mkdir

Перезагрузка системы решила проблему. Я чувствую себя подобно, возможно, что это - очевидный ответ, но в Linux, столько системных изменений вступает в силу сразу или по крайней мере когда пользователь выходит и заходит. Это конкретное изменение, однако, потребовало перезагрузки.

13
21.09.2012, 03:31
5 ответов

Можно сделать это со сценарием оболочки.

Чистый sh - это будет работать даже над оболочками Bourne предPOSIX:

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

Если Вы хотите создать высокое количество каталогов, можно сделать сценарий быстрее путем сокращения его до единственного вызова mkdir а также использование оболочки builtins для тестирования и арифметики. Как это:

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

mkdir s{1..50}
31
27.01.2020, 19:52
  • 1
    +1 Здорово! Я должен придраться к мелочам об одной вещи, хотя: n=$(( n + 1 )) был бы так же, как строго POSIX и не будет стоить Вам подоболочки. ответ –  kojiro 21.09.2012, 08:04
  • 2
    @rahmu [[ ключевым словом не является POSIX. (Не говоря уже о том, что [ оболочка, встроенная во многих современных оболочках.) –  kojiro 21.09.2012, 15:03
  • 3
    @kojiro: [[ продолжает работать мой ksh88 (который предшествует bash) таким образом, я предположил, что это был POSIX. Я не мог найти упоминание о нем в спецификации POSIX, таким образом, я полагаю, что Вы правы. Спасибо за информацию! –  rahmu 21.09.2012, 15:23
  • 4
    я думал о добавлении версии с помощью арифметического расширения, но хотел ограничить "чистый sh" для наполнения, который будет работать над версиями предPOSIX также. Я также не упоминал seq по той же причине - если у Вас есть seq, у Вас, вероятно, есть удар. Пример цикла также хорош для обхода пределов аргумента для большего числа каталогов, которое также означает, что существует место для for i in {range} для пользователей усовершенствованных оболочек. –  Random832 21.09.2012, 17:50
  • Один

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

    mkdir s{1..50}
    

    Эта опция работает в ударе, zsh и ksh93

  • Три

    mkdir $(printf "s%02i " $(seq 1 50))
    
33
27.01.2020, 19:52
  • 1
    Почему Вы когда-либо использовали бы более чем два? –  Kevin 21.09.2012, 04:46
  • 2
    можно хотеть сделать больше с $i чем просто делают каталог, например, mkdir s$i ; echo $i > s$i/$i. Кроме того, Каждый - хороший, простой пример использования для цикла в ударе... на сайте как это, это нисколько не маловероятно для неопытного пользователя видеть его и думать "хорошее, я не понял, что Вы могли сделать это"---> просвещение. –  cas 21.09.2012, 05:47
  • 3
    @rahmu Это - функция, найденная в Bash/Zsh (вероятно, ksh93 также). Никакая потребность к downvote. –  helpermethod 21.09.2012, 15:58
  • 4
    @rahmu: Я думаю, что нужно только рассмотреть, решает ли ответ jhonathan проблему с оболочкой OP (удар), не обязательно с другими. –  Francesco Turco 21.09.2012, 17:20
  • 5
    @Kevin, в то время как это вряд ли будет проблема для пятьдесят, если у Вас будет пятьсот каталогов для создания, Вы могли бы волноваться о пределах аргумента. –  Random832 21.09.2012, 17:49

Много сложных ответов здесь, но удар делает это действительно легким. Несомненно, чистые работы решения 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
10
27.01.2020, 19:52

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

или если бы Вы хотите дополненные нулем числа (который был бы лучше для сортировки):

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

или:

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

и, наконец: mkdir $(printf "s%02i " $(seq 1 50))

seq от GNU Coreutils

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

Так или иначе, двойной формат с 0 десятичной точностью как %.0f или %02.0f достаточно близко к целому числу с этой целью.

$ seq --help
Usage: seq [OPTION]... LAST
  or:  seq [OPTION]... FIRST LAST
  or:  seq [OPTION]... FIRST INCREMENT LAST
Print numbers from FIRST to LAST, in steps of INCREMENT.

  -f, --format=FORMAT      use printf style floating-point FORMAT
  -s, --separator=STRING   use STRING to separate numbers (default: \n)
  -w, --equal-width        equalize width by padding with leading zeroes
      --help     display this help and exit
      --version  output version information and exit

If FIRST or INCREMENT is omitted, it defaults to 1.  That is, an
omitted INCREMENT defaults to 1 even when LAST is smaller than FIRST.
FIRST, INCREMENT, and LAST are interpreted as floating point values.
INCREMENT is usually positive if FIRST is smaller than LAST, and
INCREMENT is usually negative if FIRST is greater than LAST.
FORMAT must be suitable for printing one argument of type `double';
it defaults to %.PRECf if FIRST, INCREMENT, and LAST are all fixed point
decimal numbers with maximum precision PREC, and to %g otherwise.

См. также: http://www.gnu.org/software/coreutils/manual/html_node/seq-invocation.html

5
27.01.2020, 19:52
  • 1
    {1,50} или {01,50} (для дополнения нуля), намного легче и более понятен. –  Kevin 21.09.2012, 04:48
  • 2
    , верный..., если Вы используете удар, а не sh. вот почему я ответ upvoted @Random832. это - хороший ответ. использование seq является также полезным ответом. –  cas 21.09.2012, 05:27

Только, чтобы отличаться, вот является 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
4
27.01.2020, 19:52

Теги

Похожие вопросы