如何优化多个sed替换序列?

时间:2017-05-16 12:19:42

标签: regex bash sed substitution

我正在尝试从不必要的重复中清除一些bash代码。目前它看起来像这样(示例值):

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"

我一直在考虑将模式和替换放在2个数组中:

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

但我不知道如何合并最终结果,以便我可以接收并运行最终命令:

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

我们的想法是能够以干净和可读的方式添加更多模式和替换,而无需修改执行它们的实际命令。

这样做的最佳方式是什么?

1 个答案:

答案 0 :(得分:2)

在循环中创建一个参数数组:

#!/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[@]}"

顺便说一下:一旦我做到这一点,我就用Perl重写脚本。

如果您不想分开模式和替换,请为两者使用一个数组并增加步骤:

#!/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[@]}"