2016-02-25 62 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)。看看当模式包含空格时会发生什么。 –