george
george

Reputation: 462

How to optimize a sequence of multiple sed replacements?

I am trying to clean-up some bash code from unnecessary repetiotions. Currently it looks like this (example values):

pattern1='aaa'
pattern2='bbb'
pattern3='ccc'

replacement1='XX'
replacement2='YY'
replacement3='ZZ'

tail $LOGS |
sed -e "s/${pattern1}/${replacement1}/g" \
    -e "s/${pattern2}/${replacement2}/g" \
    -e "s/${pattern3}/${replacement3}/g"

I have been thinking to put the patterns and replacements in 2 arrays:

pattern[0]='aaa'
pattern[1]='bbb'
pattern[2]='ccc'
# ...
replacement[0]='XX'
replacement[1]='YY'
replacement[2]='ZZ'
# ...

but I don't know how to merge the final result so that I can receive and run the final command like this:

tail $LOGS | sed -e "s/aaa/XX/g" -e "s/bbb/YY/g" -e "s/ccc/ZZ/g"

The idea is to be able to add more patterns and replacements later on in a clean and readable way, without having to modify the actual command that executes them.

What is the best way to do this?

Upvotes: 0

Views: 88

Answers (1)

choroba
choroba

Reputation: 241898

Create an array of arguments in a loop:

#!/bin/bash
patterns=( 'a'
           'bcd'
           'x.*z'
)

replacements=( 'A'
               'BCD'
               'Y'
)

args=()
for (( i=0; i < ${#patterns[@]}; i++ )) ; do
    args+=(-e "s/${patterns[i]}/${replacements[i]}/g")
done

echo 'a bcd xyyyz' | sed "${args[@]}"

BTW: I'd rewrite the script in Perl once I got to this.

If you don't want to separate the patterns and replacements, use one array for both and increase the step:

#!/bin/bash
subst=( 'a'    'A'
        'bcd'  'BCD'
        'x.*z' 'Y'
)

args=()
for (( i=0; i < ${#subst[@]}; i+=2 )) ; do
    args+=(-e "s/${subst[i]}/${subst[i+1]}/g")
done

echo 'a bcd xyyyz' | sed "${args[@]}"

Upvotes: 2

Related Questions