单独使用 awk:
> echo '$$DATABASE_AWESOME$$' | awk '{sub(/.*_/,"");sub(/\$\$$/,"");print tolower($0);}'
awesome
请注意,我使用的是 FreeBSD,所以这不是 GNU awk。
但这可以单独使用 bash 来完成:
[ghoti@pc ~]$ foo='$$DATABASE_AWESOME$$'
[ghoti@pc ~]$ foo=${foo##*_}
[ghoti@pc ~]$ foo=${foo%\$\$}
[ghoti@pc ~]$ foo=${foo,,}
[ghoti@pc ~]$ echo $foo
awesome
在上述替换中,除了最后一个 (${foo,,}) 之外的所有替换都将在标准 Bourne shell 中工作。如果您没有 bash,则可以在此步骤中使用 tr:
$ echo $foo
AWESOME
$ foo=$(echo "$foo" | tr '[:upper:]' '[:lower:]')
$ echo $foo
awesome
$
更新:
每个 cmets,似乎 OP 真正想要的是从 任何包含它的文本中去除子字符串——也就是说,我们的解决方案需要考虑在他在问题中提供的字符串之前或之后出现前导或尾随空格的可能性。
> echo 'foo $$DATABASE_KITTENS$$ bar' | sed -nE '/\$\$[^$]+\$\$/{;s/.*\$\$DATABASE_//;s/\$\$.*//;p;}' | tr '[:upper:]' '[:lower:]'
kittens
如果您的路径上碰巧有pcregrep(来自devel/pcre FreeBSD 端口),您可以使用它来代替,并带有前瞻:
> echo 'foo $$DATABASE_KITTENS$$ bar' | pcregrep -o '(?!\$\$DATABASE_)[A-Z]+(?=\$\$)' | tr '[:upper:]' '[:lower:]'
kittens
(对于阅读本文的 Linux 用户:这相当于使用 grep -P。)
在纯 bash 中:
$ shopt -s extglob
$ foo='foo $$DATABASE_KITTENS$$ bar'
$ foo=${foo##*(?)\$\$DATABASE_}
$ foo=${foo%%\$\$*(?)}
$ foo=${foo,,}
$ echo $foo
kittens
请注意,这三个更新的解决方案中没有一个可以处理同一行输入中存在多个标记数据库名称的情况。这也不是问题中的要求,但我只是说......