用 bash 测试字符串中是否有句点

用 bash 测试字符串中是否有句点

我想对 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,假设您想要运行命令$iif不是如您的示例所示,包含句点,您可以这样写:

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参数扩展标志来过滤相反)包含的元素.
  • 类似xargszargs如果 和 的命令失败,则返回失败退出状态。

答案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

相关内容