使用Bash在每个子目录中执行操作

时间:2010-10-22 20:15:06

标签: bash command directory-traversal

我正在开发一个需要在特定文件夹的每个子目录中执行操作的脚本。

写这个的最有效方法是什么?

9 个答案:

答案 0 :(得分:252)

避免创建子流程的版本:

for D in *; do
    if [ -d "${D}" ]; then
        echo "${D}"   # your processing here
    fi
done

或者,如果您的操作是单个命令,则更简洁:

for D in *; do [ -d "${D}" ] && my_command; done

或者更简洁的版本(thanks @enzotib)。请注意,在此版本中,D的每个值都有一个尾部斜杠:

for D in */; do my_command; done

答案 1 :(得分:159)

for D in `find . -type d`
do
    //Do whatever you need with D
done

答案 2 :(得分:85)

最简单的非递归方式是:

for d in */; do
    echo "$d"
done

最后的/告诉我,只使用目录。

无需

  • 找到
  • AWK
  • ...

答案 3 :(得分:14)

使用find命令。

在GNU find中,您可以使用-execdir参数:

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

或使用-exec参数:

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

或使用xargs命令:

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

或使用进行循环:

for d in */; { echo "$d"; }

对于递归,请尝试使用扩展的globbing(**/)(由shopt -s extglob启用)。

有关更多示例,请参阅:How to go to each directory and execute a command?在SO

答案 4 :(得分:12)

方便的单行

for D in *; do echo "$D"; done
for D in *; do find "$D" -type d; done ### Option A

find * -type d ### Option B

选项A对于中间有空格的文件夹是正确的。此外,通常更快,因为它不会将文件夹名称中的每个单词打印为单独的实体。

# Option A
$ time for D in ./big_dir/*; do find "$D" -type d > /dev/null; done
real    0m0.327s
user    0m0.084s
sys     0m0.236s

# Option B
$ time for D in `find ./big_dir/* -type d`; do echo "$D" > /dev/null; done
real    0m0.787s
user    0m0.484s
sys     0m0.308s

答案 5 :(得分:8)

find . -type d -print0 | xargs -0 -n 1 my_command

答案 6 :(得分:7)

这将创建一个子shell(这意味着当while循环退出时变量值将丢失):

find . -type d | while read -r dir
do
    something
done

这不会:

while read -r dir
do
    something
done < <(find . -type d)

如果目录名中有空格,则任何一个都可以使用。

答案 7 :(得分:5)

你可以尝试:

#!/bin/bash
### $1 == the first args to this script
### usage: script.sh /path/to/dir/

for f in `find . -maxdepth 1 -mindepth 1 -type d`; do
  cd "$f"
  <your job here>
done

或类似......

说明:

find . -maxdepth 1 -mindepth 1 -type d: 仅查找最大递归深度为1的目录(仅限$ 1的子目录)和最小深度为1(不包括当前文件夹.

答案 8 :(得分:4)

如果目录名称包含空格,则接受的答案将在空白处打破,bash / ksh的首选语法为$()。将GNU find -exec选项与+;一起使用,例如

find .... -exec mycommand +; #this is same as passing to xargs

或使用while循环

find .... |  while read -r D
do
  ...
done