219

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

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

4

9 回答 9

317

避免创建子流程的版本:

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

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

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

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

for D in */; do my_command; done
于 2010-10-22T20:33:23.957 回答
186
for D in `find . -type d`
do
    //Do whatever you need with D
done
于 2010-10-22T20:29:20.957 回答
126

最简单的非递归方式是:

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

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

没有必要

  • 寻找
  • awk
  • ...
于 2016-11-14T08:35:37.213 回答
22

使用find命令。

在 GNUfind中,您可以使用-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循环:

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

对于递归,请尝试扩展通配符 ( **/) 代替(通过: 启用shopt -s extglob)。


更多示例请参见:如何进入每个目录并执行命令?在 SO

于 2015-09-11T22:39:31.013 回答
14

方便的单线

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
于 2014-03-20T18:03:51.640 回答
10

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

于 2010-10-22T20:18:21.337 回答
7

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

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

这不会:

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

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

于 2010-10-23T00:26:21.627 回答
6

如果目录名称中有空格,则接受的答案将在空格上中断,并且首选语法是$()bash/ksh。使用GNU find -exec 选项,+;例如

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

或使用 while 循环

find .... | while read -r D
do
    # use variable `D` or whatever variable name you defined instead here
done 
于 2010-10-22T23:19:10.210 回答
6

你可以试试:

#!/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(不包括当前文件夹.)的目录

于 2016-04-20T11:57:52.330 回答