我正在尝试使用bash脚本递归文件夹并对它们运行命令。有什么建议吗?
答案 0 :(得分:44)
如果你想要递归到目录,对那些文件中的每个文件执行命令,我会使用find
命令,而不是使用shell脚本编写任何文件,我认为。
该命令可以接收大量参数,例如type
来过滤返回的文件类型,或者exec
来执行每个结果的命令。
例如,要找到我当前所在目录下的目录:
find . -type d -exec echo "Hello, '{}'" \;
这会让我感觉像是:
Hello, '.'
Hello, './.libs'
Hello, './include'
Hello, './autom4te.cache'
Hello, './build'
Hello, './modules'
同样可以找到当前目录下的文件:
find . -type f -exec echo "Hello, '{}'" \;
这会让我这样:
Hello, './config.guess'
Hello, './config.sub'
Hello, './.libs/memcache_session.o'
Hello, './.libs/memcache_standard_hash.o'
Hello, './.libs/memcache_consistent_hash.o'
Hello, './.libs/memcache.so'
Hello, './.libs/memcache.lai'
Hello, './.libs/memcache.o'
Hello, './.libs/memcache_queue.o'
Hello, './install-sh'
Hello, './config.h.in'
Hello, './php_memcache.h'
...
有人会说“它不是壳”......但为什么要重新发明轮子呢?
(并且,在某种程度上,它是shell ^^)
有关更多信息,您可以查看:
man find
答案 1 :(得分:9)
Bash 4.0引入了globstar选项,因此构造如下:
for f in mydir/**/*
do
# operations here
done
...将在$ f的任何土地上递归行动。用“shopt -s globstar”打开它,否则**将被视为单数*。
今天在http://www.linuxjournal.com/content/globstar-new-bash-globbing-option发现了这个宝石,受到了zsh构造的启发(我默认启用了它)。
答案 2 :(得分:7)
这样的事情应该达到你的目标:
function RecurseDirs
{
oldIFS=$IFS
IFS=$'\n'
for f in "$@"
do
-----your activity here-----
if [[ -d "${f}" ]]; then
cd "${f}"
RecurseDirs $(ls -1 ".")
cd ..
fi
done
IFS=$oldIFS
}
答案 3 :(得分:3)
一些基本的shell会错过像'find'这样的命令,而且它们的一些命令不支持递归。 在这种情况下,您可以使用此脚本在树中的所有子目录中运行所需的命令:
CDIR=$(pwd)
for i in $(ls -R | grep :); do
DIR=${i%:} # Strip ':'
cd $DIR
$1 # Your command
cd $CDIR
done
如果您将上述名称命名为“recurse.sh”,请使用:
./recurse.sh <command>
示例(将所有者/组更改为树中所有文件的“root”):
./recurse.sh "chown 0:0 *"
答案 4 :(得分:2)
抱歉,我不明白你在问什么。我能猜到的最好的问题是
find -type d -exec scriptname.sh \{\} \;
答案 5 :(得分:1)
查看find
命令并检查开关-type
(使用d指定目录)和-exec
(指定要执行的命令)。
答案 6 :(得分:0)
对于大多数递归文件操作,您希望使用find
,其他答案将解释。
bash-doc包中包含一个递归bash脚本的示例。如果您已安装这些示例,它将位于/usr/share/doc/bash/examples/functions/recurse
(在Debian上)。