使用sed / awk替换文本文件的部分

时间:2015-04-02 21:04:30

标签: bash awk sed

我正在尝试在#begin和#end之间替换文件中的文本,如下所示:

# begin

# [block]
# param1=""
# param2=""

# end

读作:

# begin

[block]
param1="value1"
param2="value2"

# end

基本上,我没有注释[block]行以及属于它的param值。

2 个答案:

答案 0 :(得分:2)

by sed:

sed '/^# begin/,/^# end/{/^# \(begin\|end\)/b a;s/^# *//; :a}' your_file > new_file

它有点复杂:

/^# begin/,/^# end/         # match from begin to end
{
    /^# \(begin\|end\)/b a; # if it's begin or end, jump to label a
    s/^# *//;               # delete all sharps
     :a                     # label a locates at the end
}

演示:

$ cat f
# begin

# [block]
# param1=""
# param2=""

# end

$ sed '/^# begin/,/^# end/{/^# \(begin\|end\)/b a;s/^# *//; :a}' f
# begin

[block]
param1=""
param2=""

# end

答案 1 :(得分:2)

使用Mac OS X的BSD sed 1

的一种更简单的解决方案,可以避免不必要的循环:
/# begin/,/# end/ {    # Search only within this range of text.
  //!s/^# //           # Excluding range borders, delete /^# / from each line.
}

测试:

▶ cat > FILE <<EOF
aaa
bbb
# begin

# [block]
# param1=""
# param2=""

# end
ccc
ddd
EOF
▶ sed -i '' '/# begin/,/# end/{//!s/^# //;}' FILE
▶ cat FILE
aaa
bbb
# begin

[block]
param1=""
param2=""

# end
ccc
ddd

进一步的解释:

  • 请注意,空正则表达式//会重复最后一个正则表达式匹配项。因此,//!对此予以否定。 /PAT1/,/PAT2/{ //! X }的作用是同时排除/PAT1/的{​​{1}}和/PAT2/

1 并使用GNU sed进行了测试。