![用 bash 测试字符串中是否有句点](https://linux22.com/image/28578/%E7%94%A8%20bash%20%E6%B5%8B%E8%AF%95%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E6%98%AF%E5%90%A6%E6%9C%89%E5%8F%A5%E7%82%B9.png)
我想对 Drupal 的 drush 命令行界面的输出运行 bash 命令。drush site-alias
返回 webroot 列表,首先显示组的名称,然后显示该组中的每个站点。该网站本身的别名为group.site
。例如,您可能会得到
内部 内部.site1 内部.site2 外部 外部.site1 外部.site2 营销 营销.site1 营销.site2
我想对每个站点别名执行命令,而不是对组别名本身执行命令。我需要测试字符串中是否有句点,如果有,则运行它:
for i in $(drush site-alias); do {if no period) drush $i command; done;
我怎样才能运行这个测试?
答案1
您可以使用模式匹配:
for i in $(drush site-alias) ; do
if [[ $i == *.* ]] ; then
drush "$i" command
fi
done
答案2
对于任何类似 POSIX 的 shell,假设您想要运行命令$i
if不是如您的示例所示,包含句点,您可以这样写:
case $i in
(*.*) ;; # contains "."s, do nothing
(*) drush "$i" command;;
esac
请注意,如果$(drush site-alias)
不加引号,则会对其执行 split+glob。您想要的分割,$IFS
默认情况下是在(空格、制表符和换行符(加上 zsh 中的 NUL))的字符上完成的,而您不想要的通配符会将单词/*
变成所有非隐藏文件或 中的目录/
。
在 GNU 系统上,并且使用支持 Ksh 样式进程替换的 shell,例如 GNU shell (bash),并假设该命令输出一站点别名每行,你可以这样做:
xargs -rd '\n' -a <(drush site-alias | grep -vF .) -I@ drush @ command
这有几个优点:
- 没有通配符
- 无论
$IFS
发生什么情况,仅在换行符和换行符上正确分割 - 不将整个输出存储在内存中,并在开始输出内容
drush
后立即开始运行命令drush site-alias
- 如果任何一个
drush command
失败,该失败将反映在xargs
的退出状态上。
请注意,如果有任何失败,drush site-alias
仍会被忽略。
有了zsh
,你可以这样做:
autoload zargs
site_aliases=( ${(f)"$(drush site-alias)"} ) || exit
zargs -I@ -- ${site_aliases:#*.*} -- drush @ command
在哪里:
- 我们还仅使用
f
参数扩展标志在换行符上进行分割(空行被丢弃)。 - 我们处理失败
drush site-alias
(这里通过退出脚本) ${site_aliases:#*.*}
过滤器出去(添加M
参数扩展标志来过滤在相反)包含的元素.
- 类似
xargs
,zargs
如果 和 的命令失败,则返回失败退出状态。
答案3
您可以通过模式替换扩展来做到这一点:
for i in $(drush site-alias); do
if [ -z "${i//[^.]/}" ]; then
# no period
drush "$i" command
fi
done
是的,我引用了"$i"
,这可能是您在可能的情况下应该做的事情,它可以避免意外。尽管在这种情况下这并不重要。
答案4
只是为了另一个独立的答案,我建议使用shell 参数扩展。
for i in $(drush site-alias)
do
if [[ ${i%.*} == $i ]]
then
drush $i command
fi
done