Adspectus
Adspectus

Reputation: 11

Can I use bash associative array as replacement in sed?

I have defined an array of weekdaynames in bash and would like to replace a numeric value enclosed in <> by the name of the weekday using sed.

The array is defined like this:

declare -A DAYNAME=( ["1"]="Mon" ["2"]="Tue" ["3"]="Wed" ["4"]="Thu" ["5"]="Fri" ["6"]="Sat" ["7"]="Sun" )

This is working:

uwe@Caboto:~$ echo "Today is <5>" | sed -e "s/<\([1-7]\)>/\1/"
Today is 5

This is also working:

uwe@Caboto:~$ echo "Today is <5>" | sed -e "s/<\([1-7]\)>/${DAYNAME[5]}/"
Today is Fri

However, this is not working:

uwe@Caboto:~$ echo "Today is <5>" | sed -e "s/<\([1-7]\)>/${DAYNAME[\1]}/"
Today is Mon

I already tried other syntaxes but could not get a way to replace the number with the value in DAYNAME.

Is there a reason why it does not work?

Upvotes: 0

Views: 341

Answers (1)

Inian
Inian

Reputation: 85800

The reason why it doesn't work is by the time your back-reference \1 is expanded to its constituent string, the array reference using the string value would become too late to be retrieved. You could get away using double expansion of the variable (e.g. using eval) which would not look good.

If you are using a associative array for reference which is "part" of the bash toolkit, use the regex functionality from the same too.

declare -A DAYNAME=( ["1"]="Mon" ["2"]="Tue" ["3"]="Wed" ["4"]="Thu" ["5"]="Fri" ["6"]="Sat" ["7"]="Sun" )

Define regex to match the day as

str="Today is <5>"
re='^(.*)<([1-7])>$'

And use the regex operator

if [[ $str =~ $re ]]; then
    day="${DAYNAME[${BASH_REMATCH[2]}]}"
    pre="${BASH_REMATCH[1]}"
    printf '%s\n' "${pre}${day}"
fi

Upvotes: 1

Related Questions