递归读取文件夹并对每个文件夹执行命令

Jin*_*hua 21 bash shell

我正在尝试使用bash脚本递归文件夹并对它们运行命令.有什么建议?

Pas*_*TIN 48

如果你想要递归到目录,对那些文件中的每个文件执行命令,我会使用find命令,而不是使用shell脚本编写任何东西,我想.

该命令可以接收大量参数,例如type过滤返回的文件类型,或者exec对每个结果执行命令.


例如,要查找我当前所在目录下的目录:

find . -type d -exec echo "Hello, '{}'" \;
Run Code Online (Sandbox Code Playgroud)

哪个会给我一些像:

Hello, '.'
Hello, './.libs'
Hello, './include'
Hello, './autom4te.cache'
Hello, './build'
Hello, './modules'
Run Code Online (Sandbox Code Playgroud)


同样找到当前目录下的文件:

find . -type f -exec echo "Hello, '{}'" \;
Run Code Online (Sandbox Code Playgroud)

这将得到这样的东西:

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'
...
Run Code Online (Sandbox Code Playgroud)


有人会说"它不是壳"......但为什么要重新发明轮子呢?
(并且,在某种程度上,它是壳^^)


有关更多信息,您可以查看:


小智 9

Bash 4.0引入了globstar选项,所以构造如下:

for f in mydir/**/*
do
  # operations here
done
Run Code Online (Sandbox Code Playgroud)

......将在$ f的任何土地上递归行动.用"shopt -s globstar"打开它,否则**将被视为单数*.

今天在http://www.linuxjournal.com/content/globstar-new-bash-globbing-option中找到了这个宝石,受到了zsh结构的启发(我默认启用了它).


小智 7

一些基本的 shell 缺少像“find”这样的命令,并且它们的一些命令不支持递归。在这种情况下,您可以使用此脚本在树中的所有子目录中运行所需的命令:

CDIR=$(pwd)
for i in $(ls -R | grep :); do
    DIR=${i%:}                    # Strip ':'
    cd $DIR
    $1                            # Your command
    cd $CDIR
done
Run Code Online (Sandbox Code Playgroud)

如果您将上述名称命名为“recurse.sh”,则使用:

./recurse.sh <command>
Run Code Online (Sandbox Code Playgroud)

示例(将树中所有文件的所有者/组更改为“root”):

./recurse.sh "chown 0:0 *"
Run Code Online (Sandbox Code Playgroud)


dre*_*old 6

这样的事情应该达到你的目标:

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
}
Run Code Online (Sandbox Code Playgroud)