2013-02-21 113 views
3

我想写一个bash脚本递归通过一个目录,并在每次着陆时执行一个命令。来自基地的每个文件夹都有前缀“lab”,我只想通过这些文件夹递归。而无需通过文件夹递归去一个例子是:递归改变目录,并在每个执行一个命令

#!/bin/bash 

cd $HOME/gpgn302/lab00 
scons -c 
cd $HOME/gpgn302/lab00/lena 
scons -c 
cd $HOME/gpgn302/lab01 
scons -c 
cd $HOME/gpgn302/lab01/cloudpeak 
scons -c 
cd $HOME/gpgn302/lab01/bear 
scons -c 

虽然这个作品,如果我想添加在说lab01更多的目录,我将不得不修改剧本。先谢谢你。

回答

3

使用find对于这样的任务:

find "$HOME/gpgn302" -name 'lab*' -type d -execdir scons -c . \; 
+0

'exec'不改变目录; 'execdir'呢。 – 2013-02-21 00:26:29

+0

它也不会限制它到实验室目录 – 2013-02-21 00:29:45

+0

你是对的。现在已经修复了。 – 2013-02-21 09:21:41

2

可以很容易地使用find查找并执行命令。

下面是其运行命令之前,变成正确的目录为例:

find -name 'lab*' -type d -execdir scons -c \; 

更新: 按thatotherguy的评论,这是行不通的。 find -type d将仅返回目录名称,但-execdir命令在包含匹配文件的子目录上运行,因此在此示例中scons -c命令将在找到的lab*目录的父目录中执行。

使用thatotherguy的方法或本非常相似:

find -name 'a*' -type d -print -exec bash -c 'cd "{}"; scons -c' \; 
+0

这不会在$ HOME/gpgn302/lab00/lena中运行命令 – 2013-02-21 00:28:21

+0

@thatotherguy您是对的。我会留下一些说明,为什么这不起作用。 – 2013-02-21 00:36:49

0

如果你想使用bash做到这一点:

#!/bin/bash 

# set default pattern to `lab` if no arguments 
if [ $# -eq 0 ]; then 
    pattern=lab 
fi 

# get the absolute path to this script 
if [[ "$0" = /* ]] 
then 
    script_path=$0 
else 
    script_path=$(pwd)/$0 
fi 

for dir in $pattern*; do 
    if [ -d $dir ] ; then 
    echo "Entering $dir" 
    cd $dir > /dev/null 
    sh $script_path dummy 
    cd - > /dev/null 
    fi 
done 
6

有几个亲密的建议,在这里,但这里有一个实际作品:

find "$HOME"/gpgn302/lab* -type d -exec bash -c 'cd "$1"; scons -c' -- {} \; 
+0

为什么将{}作为参数传递。为什么不把它嵌入$ 1所在的字符串?我很好奇b/c我不止一次地使用了后一种方法,而不是传递方式。 – 2013-02-22 05:25:56

+0

因为如果目录名称包含反引号或美元符号,则会失败,更糟的是,允许代码注入。 – 2013-02-22 05:52:33

相关问题