user3228279
user3228279

Reputation: 73

do sed to delete only if exist variable

I have this expression:

// Initially variables set to "" before process

HOSTS_APACHE=""

HOSTS=""

// Some process ...

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

It works well when apache hosts exists in a group of hosts (after processing). But it doesn't work when I have a group of hosts ($HOSTS) and I don't have any apache host to exclude.

So I need a similar expression to do SED of $HOSTS_APACHE in case there are apaches in $HOSTS and don't do anything in case there aren't.

Now the error when there aren't $HOSTS_APACHE to exclude in $HOSTS

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

Upvotes: 2

Views: 167

Answers (2)

amphetamachine
amphetamachine

Reputation: 30613

Edit: If I gather OP correctly, the issue -- or perhaps a secondary issue -- is that HOSTS_APACHE is an unordered, space-separated list of hosts or host names. In that case the solution is thus:

if [ -n "$HOSTS_APACHE" ]; then
    HOSTS_CANAL_TMP=$(echo $HOSTS | sed "s/${HOSTS_APACHE// /\\|}//g")
else
    HOSTS_CANAL_TMP=$HOSTS
fi

Explanation:

If HOSTS_APACHE is "bar baz" then ${HOSTS_APACHE// /\\|} will be "baz\|bar". The variable expansion using the double // is a global replacement of " " (space character) with \|.

Old post:

There's more than one way to accomplish this:

HOSTS_CANAL_TMP=$(echo $HOSTS |
    if [ -n "$HOSTS_APACHE" ]; then
        sed "s/$HOSTS_APACHE//"
    else
        cat # pass through
    fi)

[ -n STRING ] returns 0 if STRING has a non-zero length.

The reason |if ...; fi works is because the if structure acts as a miniature program that receives STDIN and writes to STDOUT. Which program it invokes to process I/O is chosen by the if clause.

Alternatively, you could use the if-then-else structure outside the subshell:

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

Upvotes: 2

tripleee
tripleee

Reputation: 189587

You don't really need sed here at all.

export HOSTS_CANAL_TMP=${HOSTS//"$HOSTS_APACHE"/}

The ${var//str/subst} syntax is Bash-specific (but so is putting export before an assignment, so I'm guessing that's safe here).

However, the entire problem statement looks like you should be using an array instead.

HOSTS=(foo bar baz)
HOSTS_CANAL_TMP=("${HOSTS[@]/#$HOSTS_APACHE}")

The double quotes are for safety, but will result in an empty element in HOSTS_CANAL_TMP. If you know the values in HOSTS can safely be used without quotes, you can fix that by taking out the double quotes.

Upvotes: 1

Related Questions