我有这个表达:
// Initially variables set to "" before process
HOSTS_APACHE=""
HOSTS=""
// Some process ...
export HOSTS_CANAL_TMP=$(echo $HOSTS | sed "s/$HOSTS_APACHE//")
当一组主机中存在apache主机(处理后)时,它运行良好。但是当我有一组主机($HOSTS
)并且我没有任何apache主机要排除时,它不起作用。
所以我需要一个类似的表达来执行$HOSTS_APACHE
的SED,以防$HOSTS
中存在apach,并且在没有任何事情的情况下不做任何事情。
现在在$HOSTS_APACHE
$HOSTS
时出现错误
sed: -e expression #1, char 0: no previous regular expression
答案 0 :(得分:2)
编辑:如果我正确收集OP,则问题 - 或许是次要问题 - 是HOSTS_APACHE是无序,以空格分隔的主机列表或主机名。在这种情况下,解决方案是:
if [ -n "$HOSTS_APACHE" ]; then
HOSTS_CANAL_TMP=$(echo $HOSTS | sed "s/${HOSTS_APACHE// /\\|}//g")
else
HOSTS_CANAL_TMP=$HOSTS
fi
说明:
如果HOSTS_APACHE
为"bar baz"
,则${HOSTS_APACHE// /\\|}
将为"baz\|bar"
。使用双//
的变量扩展是"的全局替换。 " (空格字符)\|
。
旧帖子:
实现这一目标的方法不止一种:
HOSTS_CANAL_TMP=$(echo $HOSTS |
if [ -n "$HOSTS_APACHE" ]; then
sed "s/$HOSTS_APACHE//"
else
cat # pass through
fi)
如果[ -n STRING ]
的 n 长度为零,则 STRING
会返回0。
|if ...; fi
工作的原因是因为if结构充当接收STDIN并写入STDOUT的微型程序。它调用哪个程序来处理I / O由if
子句选择。
或者,您可以在子shell外部使用if-then-else结构:
if [ -n "$HOSTS_APACHE" ]; then
HOSTS_CANAL_TMP=$(echo $HOSTS | sed "s/$HOSTS_APACHE//")
else
HOSTS_CANAL_TMP=$HOSTS
fi
答案 1 :(得分:1)
你根本不需要sed
。
export HOSTS_CANAL_TMP=${HOSTS//"$HOSTS_APACHE"/}
${var//str/subst}
语法是特定于Bash的(但是在分配之前将export
放在一边,所以我在这里猜测这是安全的。)
但是,整个问题陈述看起来应该使用数组。
HOSTS=(foo bar baz)
HOSTS_CANAL_TMP=("${HOSTS[@]/#$HOSTS_APACHE}")
双引号是为了安全,但会导致HOSTS_CANAL_TMP
中的空元素。如果你知道HOSTS
中的值可以安全地使用而没有引号,你可以通过取出双引号来解决这个问题。