2015-08-18 44 views
1

这是我为POSIX shell编写的shell脚本。我瞄准POSIX外壳兼容性。有一个PATTERNS变量包含冒号分隔的glob模式。这个变量是用户输入。我无法改变这一点。其余的代码是我的代码,我可以改变它来达到我的目的。下面的小演示程序的目的是在单独的行上记录(或显示)每个全局模式。如何通过冒号分割冒号分隔的glob模式时防止扩展模式扩展?

PATTERNS=*.*:*.txt:*.html 
IFS=: 
for pattern in $PATTERNS 
do 
    unset IFS 
    echo Pattern: "$pattern" 
done 

这是当前的工作目录。

$ ls 
a.txt b.txt foo.sh 

当我运行代码时,我得到了这个输出。

$ sh foo.sh 
Pattern: a.txt 
Pattern: b.txt 
Pattern: foo.sh 
Pattern: a.txt 
Pattern: b.txt 
Pattern: *.html 

而不是在一行中显示每个全局模式,它显示每个文件,在一行中与全局模式匹配。由于*.html与当前目录中的任何文件都不匹配,因此只会根据需要显示此全局模式。

我想要的输出是:

Pattern: *.* 
Pattern: *.txt 
Pattern: *.html 

所以我希望glob模式将不会扩展到当前目录中的文件名。我怎样才能做到这一点?该解决方案必须适用于任何POSIX shell。

回答

0

不积极我没有错过任何东西,或者没有更好的方法,但是这个作品并没有使用我知道的任何不可移植的东西。

#!/bin/sh 

PAT="*.rc:*.rpms:*.sh" 

# Function so we can repeatedly expand the remaining string. 
read_next() { 
    IFS=: read hd tl <<EOF 
$1 
EOF 
} 

tl=$PAT 
while read_next "$tl" && [ -n "$hd" ]; do 
    echo "Pattern: $hd" 
done 

或者,这是简单的,但它需要的“全局” IFS修改它,我从来没有的(我非常喜欢上read作用域IFS修改)的风扇,以及修改你可以全球shell设置只需简单地将-f标志的路径名扩展完全禁用到set(如果需要,然后再用set +f重新启用它),然后保持原始循环。

+1

感谢您使用代码示例的详细回复。你有没有考虑使用'set + f'来禁用glob扩展?你看到使用它的任何问题?它似乎在POSIX中定义在http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set。 –

+0

我做到了。我的意思是检查,然后提到,但实际上却显然忘了这么做。 –