如何在所有子目录中创建目录?


34

假设我有一个像这样的目录结构:

$ [〜/ practice] ls
A B C D/

现在,我想tmp1在的所有子目录中创建一个目录,practice并执行以下操作:

$ [〜/ practice] mkdir * / tmp1
mkdir:无法创建目录“ * / tmp1”:没有此类文件或目录

然后我尝试进行-p切换,最后得到一个以子目录命名*的目录tmp1

$ [〜/ practice] mkdir -p * / tmp1

$ [〜/ practice] ls
*/ A B C D/

我知道-pswitch 的用途是创建多个不存在的目录。我只是认为这可能会有所帮助。

如何tmp1一次在所有子目录中创建?

如果可以做到这一点,我如何延长它来创建\tmp1\tmp2\tmp3\a\b\c在一次?

编辑:我错过提的是,目录不必是简单而有序,像abc等等,并且要创建的目录不一定喜欢tmp1tmp2

$ [〜/ practice] ls
狗/猫/老鼠/

我想在他们身上有一些

$ [〜/ practice] ls *
狗:
红蓝/

猫:
红蓝/

鼠:
红蓝/

1
根据克里斯托弗(Christopher)的回答,您应该澄清“在\ a,\ b和\ c中创建\ tmp1,\ tmp2,\ tmp3”应该总共产生3个还是9个子目录。
manatwork 2013年

@manatwork:很好。它应该创建9个子目录。
Animesh 2013年

这对解决目录sudo find中的空间问题有帮助。/ -depth -type d -exec echo'“ {} / RCS”'\;

Answers:


44

带有小

for dir in */; do mkdir -- "$dir/tmp1"; done

注意

  • 我只将dirs(包括指向dirs的符号链接)与使用*/glob作为小技巧
  • 如果要一次创建多个子目录:

    for dir in */; do mkdir -- "$dir"/{tmp1,foo,bar,qux}; done


我可以for i in */; do mkdir "$i/itemone" "$i/itemtwo"; done为多个按顺序排列的目录名吗?
Animesh 2013年

我对此进行了测试,这很有可能。谢谢。
Animesh 2013年

请参阅我的编辑文章
Gilles Quenot 2013年

1
括号扩展未在带引号的字符串中执行。
manatwork

是的,谢谢,Stephane Chazelas编辑了相应的帖子……
Gilles Quenot

10

[...]如何扩展它以一次在\ a,\ b和\ c中创建\ tmp1,\ tmp2,\ tmp3?

 mkdir {a,b,c}/tmp{1,2,3}

10

使用GNU或BSD *查找:

find -mindepth 1 -maxdepth 1 -type d -exec mkdir {}/newdir \;

或使用参数扩展:

dirs=(*/)
mkdir -- "${dirs[@]/%/newdir}"

*包括OS X


2
随着标准查找语法:find . -name . -o -prune -type d -exec sh -c 'exec mkdir "$1/newdir"' sh {} \;
斯特凡Chazelas

1
还要注意两种解决方案之间的区别:第一种解决方案包括隐藏目录,第二种解决方案将在由当前目录中任何符号链接链接的目录中添加newdir。
斯特凡Chazelas

6

因为您提到了bash,所以话题不对,但为了记录在案,使用zsh,您可以:

dirs=(*(/))
mkdir -- $^dirs/tmp1

$^var打开类似括号的扩展以扩展数组。它让人想起rc^operator和in rc(或其派生的es),您可以这样写:

dirs=(*/)
mkdir -- $dirs^tmp1

但是请注意(此处给出的bash解决方案dirs也是如此),在rc解决方案中还将包含指向目录的符号链接。在zsh解决方案中,如果要包括指向目录的符号链接,请更改*(/)*(-/)


+1您关于符号链接的观点!可能需要这种行为,但是可以使用该-p标志来抑制mkdir关于创建重复目录的抱怨。
kojiro

4

可移植地,遍历父目录:

for d in */; do mkdir "$d/red" "$d/blue"; done

如果您的目录名称以开头,请--在后面添加。mkdir-

在zsh中,您可以使用e glob限定符在单个命令中完成此操作:

mkdir *(/e\''REPLY=($REPLY/{red,blue})'\')

但是将其键入为两个命令更快:

d=(*(/)); mkdir $^d/{red,blue}

1
在要作为参考的网站上,我宁愿说“ mkdir -- whatever,如果您打算扩展任何可能用作命令选项的内容,请省略 。”。忽略这里是没有意义的。在OP的情况下可能不是问题,但在一般情况下是一个问题。我认为我们有责任在这里教授正确和安全的语法。--mkdir--
斯特凡Chazelas

@StephaneChazelas在脚本上下文中,--当不支持换行符时,我总是放置所有必要的引号和大号警告。在命令行上下文中,我更喜欢展示首先在实践中起作用的快速版本,并以防弹版本作为补充。
吉尔(Gilles)'所以


1

避免非目录文件的sputnick答案的变体:

for x in *; do if [ -d "$x" ]; then mkdir "$x/tmp1"; fi; done

我只看Dirs,这就是所有的魔力……
Gilles Quenot 2013年

很酷,懂了;)
goldilocks

2
那不是if [ -d "$x" ];…吗?
kojiro

是。我实际上在文件名中从来没有空格,而且往往会忘记这些东西……
goldilocks 2013年

1

如果您想对/ etc / *配置文件进行版本控制(在RCS检查中锁定:ci -l并带有简短注释,例如ir:对于初始发行版),则这是旧Unix Master(在FreeBSD 10.1上测试)的一个好选择。在〜/ .his / etc上

sudo rsync -av /etc/ ~/.his
sudo find -d ~/.his/etc -type d -exec echo '{}/RCS' \; | xargs sudo mkdir -p
sudo find -d ~/.his/etc \! -name "RCS" | xargs sudo ci -l -mir -t-ir

我看不到如何回答OP
Archemar

1

应该 \!名称为“ RCS”,并且在首次签入时效果最佳。

sudo查找〜/ .his / etc \!名称“ RCS” -ls

须藤查找-d〜/ .his / etc \!名称“ RCS” | xargs sudo ci -l -mir -t-ir

这最后一点对于cjeck也非常有效,它可以部分过滤文件名上的所有RCS内容:

须藤查找-d〜/ .his / etc -type f | grep -v RCS | xargs sudo ci -l -mir -t-ir


1

这对我有很大的帮助。我需要在多个文件夹中创建一组子目录,如下所示:

!/bin/sh

cd /dest/cont

for dir in */*/; do
    mkdir -p -- $dir/{FB,Video,Audio,proj};
done

效果很好,除非遇到空白。有没有办法忽略*/*/部分参数中的空格?

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.