shime
shime

Reputation: 9008

sed - using array to build regex

I'm having problems constructing regular expression from array of strings, for use in sed command.

Here's an example

#!/usr/bin/env bash

function join { local IFS="$1"; shift; echo "$*"; }

array=("foo" "bar" "baz")
regex=$(join "\|" "${array[@]}") # foo|bar|baz

echo "foo bar baz" | sed "s/${regex}/replaced/g"

I'm expecting this to output replaced replaced replaced, but it's returning foo bar baz since this regex is not hitting anything. The pipes in the regex are not being escaped correctly here.

What am I doing wrong?

Upvotes: 0

Views: 214

Answers (2)

anubhava
anubhava

Reputation: 785246

You need to use:

regex=$(join '|' "${array[@]}")

Since IFS accepts only one character.

Then use (for BSD):

echo "foo bar baz" | sed -E "s/${regex}/replaced/g"

OR for Linux:

echo "foo bar baz" | sed -r "s/${regex}/replaced/g"

EDIT: If you want to avoid using extended regex option in sed then refactor your join function like this:

join() { sep="$1"; shift; echo -n "$1"; shift; printf "$sep%s" "$@"; }

Then use it as:

regex=$(join '\|' "${array[@]}")
echo "foo bar baz" | sed "s/${regex}/replaced/g"
replaced replaced replaced

Upvotes: 1

Wintermute
Wintermute

Reputation: 44043

| needs to be escaped in basic regex syntax. Either use extended syntax:

sed -r "s/${regex}/replaced/g"          # GNU sed. With BSD sed, use -E

Or build the regex so that it is foo\|bar\|baz.

Upvotes: 2

Related Questions