使用mkdir创建许多目录


14

我想使用创建许多目录mkdir。每个目录名称将由一个前缀(一个字符串)和一个索引(一个整数)组成。假设我希望前缀为“ s”,索引范围为1到50。这意味着我想创建名为:

s1s2,... s49s50

有没有一种方法可以自动使用mkdir?谢谢你的时间。


2
您正在使用哪个外壳?
Francesco Turco 2012年

我正在使用@FrancescoTurco bash。感谢您的时间!
安德鲁(Andrew)

3
仅供参考,我觉得很多更实用的使用固定宽度的指标,如:s01s02,..., ,。s49 s50如果我使用固定宽度的索引,/bin/ls几乎总是产生我想要的顺序。
罗布

Answers:


32

您可以使用Shell脚本执行此操作。

纯sh-即使在POSIX bourne之前的shell上也可以使用:

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

如果要创建大量目录,可以通过将脚本简化为单个调用mkdir以及使用shell内置函数进行测试和算术来提高脚本速度。像这样:

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,可能无法在其他shell中工作。对于较大的情况,它可能还会受到可能传递给命令的参数的数量或总大小的限制。

mkdir s{1..50}

3
+1太好了!不过,我不得不提一件事:n=$(( n + 1 ))严格按照POSIX进行操作,并且不会花费您一个subshel​​l。
kojiro 2012年

@rahmu [[关键字不是POSIX。(更不用说这[ 许多现代外壳内置的外壳。)
kojiro 2012年

@kojiro:[[在我的ksh88(早于bash)上工作,所以我认为它是POSIX。我在POSIX规范中找不到任何提及,因此我相信您是对的。谢谢(你的)信息!
rahmu 2012年

我曾考虑过使用算术扩展来添加版本,但想将“ pure sh”限制为同样适用于POSIX之前的版本。由于相同的原因,我也没有提到seq-如果您有seq,则可能是bash。循环示例也适合绕过大量目录的参数限制,这也意味着for i in {range}高级shell用户可以使用。
Random832

最后的zsh提示是惊人的,它节省了我很多时间!
亚瑟

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

    此选项适用于bashzshksh93

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

4
为什么要使用二选一?
凯文(Kevin)

7
您可能不仅想$i建立目录,还想做更多的事情,例如mkdir s$i ; echo $i > s$i/$i。另外,一个很好的简单示例是在bash中使用for循环...在这样的网站上,新手用户完全不可能看到它并认为“很好,我没有意识到您可以做到这一点” “ --->启示。
cas 2012年

1
@rahmu这是Bash / Zsh中的一项功能(也可能是ksh93)。无需投票。
helpermethod 2012年

3
@rahmu:我认为应该只考虑jhonathan的答案是否能解决OP的shell(bash)问题,而不必解决其他问题。
Francesco Turco 2012年

4
@Kevin虽然可能不会有五十个问题,但是如果有五百个目录可以使您担心参数限制。
Random832

10

这里有很多复杂的答案,但是bash确实很容易。当然,纯POSIX解决方案可以工作,但是为什么不利用bash您正在使用的shell?您可以通过大括号扩展轻松地做到这一点:

% 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-foption只允许printf的浮点双精度类型(如f和g。也是我从未发现过用处的奇怪的浮点十六进制格式)。我不知道为什么。如果它还支持其他printf(3)数字类型,例如整数(d,i),八进制(o,U)或十六进制(x,X),那将是很好的。

无论如何,具有0十进制精度的double格式例如%.0f%02.0f足以接近整数。

$ seq-帮助
用法:seq [OPTION] ... LAST
  或:seq [OPTION] ...倒数第一
  或:seq [OPTION] ...第一次递增
按递增顺序从第一到最后打印数字。

  -f,--format = FORMAT使用printf样式浮点格式
  -s,--separator = STRING使用STRING分隔数字(默认值:\ n)
  -w,--equal-width通过填充前导零来均衡宽度
      --help显示此帮助并退出
      --version输出版本信息并退出

如果省略FIRST或INCREMENT,则默认为1。
即使LAST小于FIRST,省略的INCREMENT也默认为1。
FIRST,INCREMENT和LAST被解释为浮点值。
如果FIRST小于LAST,则INCREMENT通常为正,并且
如果FIRST大于LAST,则INCREMENT通常为负。
FORMAT必须适合于打印一个类型为double的参数。
如果FIRST,INCREMENT和LAST均为固定点,则默认为%.PRECf
精度为PREC的十进制数字,否则为%g。

另请参阅:http : //www.gnu.org/software/coreutils/manual/html_node/seq-invocation.html


{1,50}{01,50}(对于零填充)更容易理解。
凯文(Kevin)

1
是的...如果您使用bash而不是sh。这就是为什么我赞成@ Random832的答案。这是一个很好的答案。使用seq也是一个有用的答案。
cas 2012年

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.