2016-02-25 54 views
1

我有一個需要glob表達式作爲參數的bash腳本。但是我在使用麻煩輸入作爲水珠即說我的輸入是將腳本參數作爲模式傳遞

Shell_script '*.c' 

和我的代碼是通過文件的數組迭代,並通過圖案匹配濾波它們。在這種情況下,沒有.c擴展名的文件。 (在這個例子中,第一個輸入可以是其他任何模式)

count=${#array[@]} 
    for ((q = 0; q < count; q++)); 
    do 
     if [[ ${array[q]} == $1 ]]; then 
       : 
     else unset array[q] 
     fi 
    done 
    ..... 

任何想法?

+0

'* .c'不是一個有效的正則表達式。你想過濾一個文件列表嗎?看起來你試圖使用的是某種全局模式。 – slugo

+0

是我試着去過濾文件列表 –

+0

你就不能在使用類似的文件循環:'在* .c文件 做 #$文件是文件 做 ' – slugo

回答

1

相同排列的內容針對水珠是完全有可能的:

#!/bin/bash 

# this array has noncontiguous indexes to demonstrate a potential bug in the original code 
array=([0]="hello.c" [3]="cruel.txt" [5]="world.c") 

glob=$1 
for idx in "${!array[@]}"; do 
    val=${array[$idx]} 
    if [[ $val = $glob ]]; then 
    echo "File $val matches glob expression $glob" >&2 
    else 
    echo "File $val does not match glob expression $glob; removing" >&2 
    unset array[$idx] 
    fi 
done 

同樣,可以擴大對文件系統內容的水珠,雖然你會首先要清除IFS以避免字符串分裂:

# here, the expectation is that your script would be invoked as: ./yourscript '*.c' 

IFS= 
for f in $1; do 
    [[ -e $f || -L $f ]] || { echo "No file matching $f found" >&2; } 
    echo "Iterating over file $f" 
done 

這就是說,一般來說,這是極端 unidiomatic,而不是讓你的腳本開始之前調用shell擴展glob,並從參數向量中讀取匹配文件的列表。因此:

# written this way, your script can just be called ./yourscript *.c 
for f; do 
    [[ -e $f || -L $f ]] || { echo "No file matching $f found" >&2; } 
    echo "Iterating over file $f" 
done 
+0

爲什麼它[[$ val = $ glob]]而不是[[$ val == $ glob]] –

+0

另外這對我沒有用 –

+0

@DarthVeder,因爲'=='在POSIX中不是有效的運算符測試。請參閱http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html中的標準文檔,它清楚地將唯一有效的字符串比較運算符記錄爲'='; bash增加了'==',但是這是一個擴展,習慣於符合標準並因此廣泛兼容的方法是更好的習慣。 –

0

您可以像這樣遍歷文件列表。如果您運行的腳本爲 ./test.sh "*.c"。然後你的腳本中,你可以這樣做:

for file in $1 
do 
    #use your file 
done 
+0

這是可能的,但如果不加以小心,這也是一個壞主意(如清除IFS)。看看當模式包含空格時會發生什麼。 –