Bash:为每个目录
我正在研究需要在特定文件夹的每个子目录中执行操作的脚本。
什么是最有效的方式来写呢?
for D in `find . -type d` do //Do whatever you need with D done
避免创build子stream程的版本:
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
最简单的非recursion方式是:
for d in */; do echo "$d" done
/
最后告诉,只使用目录。
没有必要
- 找
- AWK
- …
方便的单线
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
find . -type d -print0 | xargs -0 -n 1 my_command
使用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循环:
for d in */; { echo "$d"; }
对于recursion,尝试扩展globbing( **/
),而不是(启用: shopt -s extglob
)。
有关更多示例,请参阅: 如何前往每个目录并执行命令? 在SO
这将创build一个子shell(这意味着当while
循环退出时,variables值将会丢失):
find . -type d | while read -r dir do something done
这不会:
while read -r dir do something done < <(find . -type d)
如果目录名称中有空格,任何一个都可以工作。
你可以尝试:
#!/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
find . -maxdepth 1 -mindepth 1 -type d
:只能find最大recursion深度为1的目录(只有$ 1的子目录)和最小深度为1(不包括当前文件夹) .
如果目录名具有这些空格,则接受的答案将在空格上打破,而对于bash / ksh,首选语法是$()
。 使用GNU find
-exec
选项+;
例如
find .... -exec mycommand +;
#this is same as passing to xargs
或者使用一个while循环
find .... | while read -r D do ... done