如何在 bash 中的每个子目录中创建相同的目录?

How do I create the same directory in every subdirectories in bash?

我一直在尝试在“example”的所有子目录中创建目录“a”。

我试过的是:

mkdir example/*/a

但是它没有把'*'作为通配符,返回mkdir: cannot create «example/*/a» directory: It doesn't exist file or directory

注意我例子中的子目录太多,无法通过创建列表来实现

我不想用 for 循环来做,因为我正在学习 bash 并且不允许我使用循环。可能无法避免 for 循环,如果是这样,请告诉我 :).

谢谢。

Probably, there is no way to avoid a for loop

您可以使用 find:

find example -type d -not -name a -exec mkdir -p {}/a \;

刚刚:

for i in example/*/; do
    mkdir "$i"/a
done

我认为只有知道example下的子目录才能避免循环,例如:

mkdir example/{subdir1,subdir2,subdir3}/a

否则,使用 for 循环来拯救:

for d in example/*/; do mkdir "${d}a"; done

注意:如果您想让 mkdir 显示已创建的目录,请将 -v 添加到 mkdir

尝试:

dirs=( example/*/ )
mkdir -v "${dirs[@]/%/a}"
  • dirs=( example/*/ ) 创建一个包含 example ( (example/dir1/ example/dir2/ ...) ) 的所有子目录的数组。
  • "${dirs[@]/%/a}" 扩展为包含 dirs 的所有元素的列表,每个元素都附加了 a ( (example/dir1/a example/dir2/a ...) )。

如果您有非常 的大量子目录,上述代码中的mkdir 可能会失败并出现“参数列表太长”错误。参见 Argument list too long error for rm, cp, mv commands

避免该问题的一种方法是将要创建的目录的 NUL-terminated 列表传递给 xargs -0:

dirs=( example/*/ )
printf '%s[=11=]' "${dirs[@]/%/a}" | xargs -0 mkdir -v

这将在必要时 运行 多个 mkdir 命令,每个命令都有一个不超过限制的参数列表。

但是,如果目录数量 大,您可能 运行 由于 Bash(不必要但不可避免地)对目录进行排序而导致性能问题example/*/ 生成的列表)。在那种情况下,使用 find 会更好。一种方法是:

find example -maxdepth 1 -mindepth 1 -type d -printf '%p/a[=12=]' | xargs -0 mkdir -v

find built-in 支持与 -exec ... + 类似 xargs 的行为。但是,在这种情况下使用起来有点麻烦。我能想到的最好的是:

find example -maxdepth 1 -mindepth 1 -type d    \
    -exec bash -c 'mkdir -v "${@/%//a}"' bash {} +

因为它在 运行 宁 mkdir 之前将 /a 添加到 find 传递给 bash 的所有参数,它可能会遇到一个无论如何都会出现“参数列表太长”错误。我会把它留在这里,因为它说明了一种 sometimes-useful 技术,但我建议不要使用它。