2013-02-21 83 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

相關問題