我如何编写一个bash脚本,遍历parent_directory内的每个目录,并在每个目录中执行命令。

目录结构如下:

Parent_directory(名称可以是任何东西-不遵循模式) 001(目录名称遵循此模式) 0001.txt(文件名遵循此模式) 0002.三种 0003.三种 002 0001.三种 0002.三种 0003.三种 0004.三种 003 0001.三种 目录数量未知。


当前回答

托德发布的这个回答帮助了我。

find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd" \;

\(!- name。\)避免执行当前目录下的命令。

其他回答

你可以在每个文件夹中运行一行命令序列,比如:

for d in PARENT_FOLDER/*; do (cd "$d" && tar -cvzf $d.tar.gz *.*)); done

你可以使用

find .

递归搜索当前目录下的所有文件/dirs

然后您可以像这样通过xargs命令输出

find . | xargs 'command here'

托德发布的这个回答帮助了我。

find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd" \;

\(!- name。\)避免执行当前目录下的命令。

您可以通过管道,然后使用xargs来实现这一点。问题是您需要使用-I标志,它将用每个xargs传递的子字符串替换bash命令中的子字符串。

ls -d */ | xargs -I {} bash -c "cd '{}' && pwd"

您可能希望将pwd替换为您想在每个目录中执行的任何命令。

如果你正在使用GNU find,你可以尝试-execdir parameter,例如:

find . -type d -execdir realpath "{}" ';'

or (as for @gniourf_gniourf评论):

find . -type d -execdir sh -c 'printf "%s/%s\n" "$PWD" "$0"' {} \;

注意:您可以使用${0#。/}而不是$0来修复。/在前面。

或者更实际的例子:

find . -name .git -type d -execdir git pull -v ';'

如果你想包含当前目录,使用-exec会更简单:

find . -type d -exec sh -c 'cd -P -- "{}" && pwd -P' \;

或者使用xargs:

find . -type d -print0 | xargs -0 -L1 sh -c 'cd "$0" && pwd && echo Do stuff'

或者@gniourf_gniourf给出的类似例子:

find . -type d -print0 | while IFS= read -r -d '' file; do
# ...
done

上面的示例支持名称中带有空格的目录。


或者通过在bash数组中赋值:

dirs=($(find . -type d))
for dir in "${dirs[@]}"; do
  cd "$dir"
  echo $PWD
done

改变。到您的特定文件夹名称。如果你不需要递归运行,你可以使用:dirs=(*)代替。上面的示例不支持名称中有空格的目录。

因此,正如@gniourf_gniourf所建议的那样,在不使用显式循环的情况下,将find的输出放在数组中的唯一正确方法将在Bash 4.4中可用:

mapfile -t -d '' dirs < <(find . -type d -print0)

或者不是推荐的方式(涉及到ls的解析):

ls -d */ | awk '{print $NF}' | xargs -n1 sh -c 'cd $0 && pwd && echo Do stuff'

上面的例子会忽略当前的目录(OP请求的),但是它会中断带有空格的名称。

参见:

Bash:用于SO的每个目录 如何进入当前路径下的每个目录并执行脚本?在SE Ubuntu