2014-11-05 18 views
1

我有这样的表达:做SED只删除是否存在变量

// Initially variables set to "" before process 

HOSTS_APACHE="" 

HOSTS="" 

// Some process ... 

export HOSTS_CANAL_TMP=$(echo $HOSTS | sed "s/$HOSTS_APACHE//") 

它运作良好,当Apache主机一组主机的存在(处理后)。但是当我有一组主机时($HOSTS),并且我没有任何要排除的apache主机时,它不起作用。

所以我需要一个类似的表达式来做SED $HOSTS_APACHE以防在$HOSTS中有apaches,并且在没有的情况下不做任何事情。

现在,当没有$HOSTS_APACHE$HOSTS

sed: -e expression #1, char 0: no previous regular expression 
+0

使用'if'语句来测试'$ HOSTS_APACHE'中是否有任何内容。 – Barmar 2014-11-05 16:13:52

+0

这看起来不太好。什么是'$ HOSTS'和'HOSTS_APACHE'的典型内容? (因为复数,我担心情况会更糟)。此外,你的命令相当于参数扩展:'export HOSTS_CANAL_TMP =“$ {HOSTS/$ HOSTS_APACHE /}”'(它不会遇到你遇到的问题),除非你在$ HOSTS_APACHE中有一些正则表达式'。你能否解释你想达到的目标(你知道,ProblemXY),而不是问你想要解决你原来的问题的方法。 – 2014-11-05 16:22:11

回答

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 ]返回0,如果STRINGň上零长度。

原因|if ...; fi的工作原因是if结构充当接收STDIN并写入STDOUT的微型程序。它调用哪个程序来处理I/O是由if子句选择的。

或者,你可以使用的if-then-else结构的壳层外:

if [ -n "$HOSTS_APACHE" ]; then 
    HOSTS_CANAL_TMP=$(echo $HOSTS | sed "s/$HOSTS_APACHE//") 
else 
    HOSTS_CANAL_TMP=$HOSTS 
fi 
+0

我有四个主机,其中两个是Apache。如果订单不一样在apache的变量,apache的主机没有从主机列表 HOSTS_APACHE = “BCD DEF” HOSTS = “ABC BCD CDE DEF” 如果[-n “$ HOSTS_APACHE” 已删除]。然后 出口HOSTS_CANAL_TMP = $(回声$ HOSTS | sed的 “S/$ HOSTS_APACHE //”) 其他 出口HOSTS_CANAL_TMP = $ HOSTS 网络 – user3228279 2014-11-05 16:53:22

+0

@ user3228279我仍然有问题的理解你的意思。 – amphetamachine 2014-11-05 17:25:40

+0

我有两个变量($ HOSTS和$ HOSTS_APACHE)。 $ HOSTS_APACHE中的所有值都包含在$ HOSTS中。我想要一个名为HOSTS_CANAL_TMP的新变量,其中的所有值都不包括那些在$ HOSTS_APACHE中的值。 当: HOSTS_APACHE = “BCD CDE” HOSTS = “ABC BCD CDE DEF” 然后: HOSTS_CANAL_TMP = “ABC DEF” 当: HOSTS_APACHE = “BCD DEF” HOSTS =“ABC BCD CDE DEF “ Then: HOSTS_CANAL_TMP =”abc bcd cde def“ – user3228279 2014-11-05 17:56:28

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中的值可以安全地在没有引号的情况下使用,您可以通过删除双引号来解决该问题。