2014-03-12 16 views
2

這裏是我的bash腳本的一個小部分,但它是查找並輸出mydir中的所有文件(如果從存儲數組中有前綴的話)。我注意到奇怪的是,如果我從腳本中取出「-maxdepth 1 -name」,則該腳本完美地工作,否則它只會給我帶有數組中第一個元素的前綴的文件。Bash找到:列出所有帶有for循環前綴的文件

如果有人向我解釋這將是很大的幫助。對不起,如果有一件事顯然愚蠢,我在做。我對腳本相對來說比較陌生。

#!/bin/sh 
DIS_ARRAY=(A B C D) 
echo "Array is : " 
echo ${DIS_ARRAY[*]} 
for dis in $DIS_ARRAY 
do 
    IN_FILES=`find /mydir -maxdepth 1 -name "$dis*.xml"` 
    for file in $IN_FILES 
    do 
    echo $file 
    done 
done 

輸出:

/mydir/Abc.xml 
/mydir/Ab.xml 
/mydir/Ac.xml 

預期輸出:

/mydir/Abc.xml 
/mydir/Ab.xml 
/mydir/Ac.xml 
/mydir/Bc.xml 
/mydir/Cb.xml 
/mydir/Dc.xml 

回答

2

的環路斷開任一方式。爲什麼

IN_FILES=`find mydir -maxdepth 1 -name "$dis*.xml"` 

作品,而

IN_FILES=`find mydir "$dis*.xml"` 

不會是因爲在第一個,你指定-name原因。在第二個中,find列出了mydir中的所有文件。如果將第二個更改爲

IN_FILES=`find mydir -name "$dis*.xml"` 

您將看到循環無法正常工作。

正如在評論中提到的那樣,您當前使用的語法$DIS_ARRAY只會給你數組的第一個元素。

試着改變你的循環,這樣的:

for dis in "${DIS_ARRAY[@]}" 

在這種情況下,周圍的雙引號是沒有必要的,所以你可以這樣做:

for dis in ${DIS_ARRAY[@]} 

如果你的數組中包含引號是必需的例如,如果你想循環遍歷數組arr=("a a" "b b")

這裏的顯示是怎麼回事測試:

#!/bin/sh 

arr=("a a" "b b") 

echo using '$arr' 
for i in $arr; do echo $i; done 
echo using '${arr[@]}' 
for i in ${arr[@]}; do echo $i; done 
echo using '"${arr[@]}"' 
for i in "${arr[@]}"; do echo $i; done 

輸出:

using $arr 
a 
a 
using ${arr[@]} 
a 
a 
b 
b 
using "${arr[@]}" 
a a 
b b 

請參見本related question進一步的細節。

+0

工作,謝謝!您能否足夠解釋爲什麼以前的方法不適用於這種方法?或者它只是一個標準的語法? – Karen

+0

@Karen:引用一個不帶下標'[@]'(或等效的[*]')的數組變量只返回* first *元素的值。 – mklement0

+0

@ mklement0謝謝,我已將您的意見加入 –

1

@ TomFenech的回答解決您的問題,但讓我提出其他改進:

#!/usr/bin/env bash 

DIS_ARRAY=(A B C D) 
echo "Array is : " 
echo ${DIS_ARRAY[*]} 
for dis in "${DIS_ARRAY[@]}" 
do 
    for file in "/mydir/$dis"*.xml 
    do 
     if [ -f "$file" ]; then 
      echo "$file" 
     fi 
    done 
done 
  • 你的家當行引用sh,但你的問題是標籤bash - 除非你需要符合POSIX,使用bash家當line利用所有bash必須提供的優勢
  • 匹配位於的文件直接在給定的目錄中(即,如果您不需要遍歷整個子樹),使用glob(文件名模式)並依賴於上面的代碼中的路徑名擴展 - 不需要find和命令替換。
  • 請注意通配符字符。 *被UN引用來確保路徑名擴展。
  • 注意:如果找不到匹配的文件,glob將保持不變(假設nullglob shell選項爲OFF,默認情況下爲OFF),因此循環只輸入一次,使用無效文件名(未擴展的glob) - 因此[ -f "$file" ]有條件確保找到實際匹配(作爲旁白:使用bashisms,您可以使用[[ -f $file ]]代替)。
+0

非常感謝。你的回答確實有幫助。 – Karen

+0

@Karen:很高興聽到它。 – mklement0