可以匹配一条线的一部分并替换另一部分,对于多条线,每条线都有不同的匹配和替换?

时间:2015-05-07 09:17:42

标签: sed

给定一个包含多行格式的文件:

define('SOME_NAME', some_value);

对于多个不同的行,如何sed用于匹配SOME_NAME并将some_value替换为some_other_value

这是一行的解决方案:

sed -re "s|^(define *\('SOME_NAME'\s*,\s*).*(\);)|\1 some_other_value \2|" defs_file

要处理文件中的许多类似定义,我必须在sed之外编写脚本(此示例使用bash版本4关联数组):

#!/bin/bash
declare -A args
args=([SOME_NAME1]=some_other_value1
      [SOME_NAME2]=some_other_value2
      [SOME_NAME3]=some_other_value3
      [SOME_NAME4]=some_other_value4
      [SOME_NAME5]=some_other_value5)

for arg in "${!args[@]}"
do
  sed -i -re "s|^(define *\('$arg'\s*,\s*).*(\);)|\1 ${args[$arg]} \2|" defs_file
done

是否有更优雅的方式来实现仅依赖sed

的结果

1 个答案:

答案 0 :(得分:0)

这可能适合你(GNU sed):

sed -r 's/$/\n@NAME:new_value/;s/([^,]*),[^\n]*\n.*@\1:([^@]*).*/\1,\2/;P;d' <<<"NAME,old_value"

这是你的一个简化例子;将查找附加到模式空间,然后使用regexp和back引用来匹配和重新排列输出。有关详细说明,请参阅here

N.B。在上面的例子中(为了简洁起见)我只包括一次查找,在实际的解决方案中,查找表会有几个例如。 s/$/\n@NAME1:new_value1@NAME2:new_value2..../