我该怎么做呢?
if [ -f town-*.swf ]
then
mkdir towns
fi
这会检查是否town-*.swf
存在,但我还需要它来查找city-*.swf
其他内容,所以我需要这样的东西:
if [ -f town-*.swf, city-*.swf ]
then
mkdir towns
fi
答案1
POSIXly,你可以使用ls
if ls town-*.swf >/dev/null 2>&1 &&
ls city-*.swf >/dev/null 2>&1
then
mkdir towns
fi
或更短的 if 条件:
if ls town-*.swf city-*.swf >/dev/null 2>&1
即使你的 shell 支持大括号扩展:
if ls {town,city}-*.swf >/dev/null 2>&1
答案2
if stat -t city-*.swf >/dev/null 2>&1
then
if stat -t town-*.swf >/dev/null 2>&1
then
mkdir towns
fi
fi
正如用户 uwe 在评论中指出的那样,我之前的命令将阻止通配符扩展。然而,这个新版本应该可以工作。
如果您需要一个if
循环,您可以将脚本修改为,
if stat -t city-*.swf >/dev/null 2>&1 && stat -t town-*.swf >/dev/null 2>&1
then
mkdir towns
fi
如果您需要指定 or 条件而不是 and 条件,则可以替换&&
为||
。
测试
ls
city-1.swf city-2.swf city-3.swf city-4.swf city-5.swf sc.sh
town-1.swf town-2.swf town-3.swf town-4.swf town-5.swf
现在,我执行名为的脚本sc.sh
,然后我可以看到城市目录已成功创建。
参考
https://stackoverflow.com/questions/2937407/test-whether-a-glob-has-any-matches-in-bash
答案3
在大多数情况下,命令test ( [ )
提供操作员-a
和-o
EXPR1 -a EXPR2
如果两者都为真表达式1和表达式2是真的。
EXPR1 -o EXPR2
如果有的话则为真表达式1或者表达式2是真的。
但在可能的多行情况下,您应该使用可以在条件下运行的命令(例如ls
)
ls {town,city}-*.swf &>/dev/null && mkdir town
你可以利用这样一个事实通配当找不到替换时,字符串保持原样(在 with 的情况下*
)。所以我们只需要检查它是否在该行中:
set -- {city,town}-*.swf
[[ ! "$*" =~ \* ]] && mkdir town
或使用case
(如上面评论中提供的)
case $(ls) in
*city-*.swf*town-*.swf*) mkdir town ;;
esac
答案4
这是一个比运行外部命令影响更小的解决方案ls
,并且比基于stat
(因操作系统而异)的解决方案更可移植。
#!/bin/bash
found=false
for _ in town-*.swf, city-*.swf do
found=true; break
done
if $found; then
echo "Yup!"
fi
下划线是一次性变量。循环for
是扩展文件列表的简单方法,并确保break
您不会浪费循环遍历长文件列表的周期。可执行文件true
和可以在或false
中找到,并且可以替换为/bin/
/usr/bin/
bash 内建函数或函数如果您更喜欢这种优化。
请注意,这也应该适用于/bin/sh
. (至少,它在其他几个操作系统中对我来说是这样的。)