Reputation: 73
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
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
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