递归创建所有字母的目录


12

我想以这样一种方式创建目录,即需要将目录从标记az。在每个目录中,我需要创建子目录,以便将其标记为aaab等等。

因此,例如,对于目录m,我的子目录将被标记为mamb高达mz


3
您不需要第一个mkdir,因为-p也在创建子目录。而且,如果您使用abolute路径,则不需要cd命令。否则,它将很不错,可以工作,可以声明变量,等等。Michael Homer的版本较短,也许具有更好的性能,但是对于这样一个简单的任务,您的版本就足够了。

1
过去有很多termininfo条目,而且没有bash {a..z}语法,因此我会/usr/share/terminfo用[az] 列出并使用该输出。Linux在这一点上非常稀疏,以前是所有大写和小写字符以及数字的条目。
schemathings 2014年

Answers:


19

尝试:

for x in {a..z} ; do mkdir -p $x/${x}{a..z} ; done

Bash将展开XXX{a..z}XXXaXXXb等等。您不需要内部循环。

之后:

$ ls
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
$ ls m
ma  mc  me  mg  mi  mk  mm  mo  mq  ms  mu  mw  my
mb  md  mf  mh  mj  ml  mn  mp  mr  mt  mv  mx  mz

7

因此,使用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|commandwill将以for相同的方式通过管道流式传输循环的所有输出,done >file将其全部流式传输到文件中-整个for...done结构仅一次打开和关闭输出文件。


3

这里开始,我最终创建了这样的脚本。但是,如果我得到一个优雅的解决方案,我将接受它作为答案。

for x in {a..z}
do
    mkdir -p /home/ramesh/$x
    cd /home/ramesh/$x
    for y in {a..z}
    do
        mkdir -p /home/ramesh/$x/$x$y
    done
done

+1,好问题和更好的回答:)
Nidal

@Networker,我敢肯定有比这更好的解决方案。等待一些专家的答案,其工作将类似于此答案,但看起来会很酷:)
Ramesh 2014年

严格来说,当您知道变量值将是什么(它们是简单的字符串)时,并不必要,但是养成引用变量的习惯是一个好主意。您可以使用/home/ramesh/"$x"/"$x$y"/home/ramesh/"$x/$x$y""/home/ramesh/$x/$x$y"-等价。
斯科特

1

Perl

perl -MFile::Path=make_path -e '
    make_path(map { $l=$_; map { "$l/$l$_" } a..z } a..z)
'

File::Path是的核心模块Perl 5.001

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.