替换包含选项卡的部分行

时间:2013-07-09 13:38:41

标签: regex bash replace sed awk

如何使用sed,awk或其他任何内容替换包含制表符(\ t)的行的一部分?

该行

    <property name="systemVersionDsvTes"                value="xxx"/>

\t<property name=\"systemVersionDsvTes\"\t\t\t\tvalue=\"xxx\"/>

应替换为:

    <property name="systemVersionDsvTes"                value="yyy"/>

\t<property name=\"systemVersionDsvTes\"\t\t\t\tvalue=\"yyy\"/>

xxx 可能会有所不同,并且在属性名称前有一个标签,在值之前有四个标签。此名称 - 值对是xml文件中唯一的一个。

我尝试了以下内容:

ACTUAL_VERSION="\t<property name=\"systemVersionDsvTes\"\t\t\t\tvalue=\"4.1.9\"/>"
NEW_VERSION="\t<property name=\"systemVersionDsvTes\"\t\t\t\tvalue=\"4.1.10\"/>"
sed -i -e "s/$ACTUAL_VERSION/$NEW_VERSION/g" buildSIM.xml

导致错误:sed:-e expression#1,character 65:命令's'的未知选项(s ///?)

表达方式有什么问题?使用GNU sed。

2 个答案:

答案 0 :(得分:1)

错误消息Unknow option for command 's' (s///?)是指在第三个斜杠之后可以添加到替换命令的“选项”。这些选项包括g之类的字母来替换所有出现的模式而不仅仅是第一个模式,或i来忽略字母大小写。它通常暗示模式或替换包括额外的斜杠。要处理模式中的斜线或替换它们也必须进行转义:

ACTUAL_VERSION="\t<property name=\"systemVersionDsvTes\"\t\t\t\tvalue=\"4.1.9\"\/>"
NEW_VERSION="\t<property name=\"systemVersionDsvTes\"\t\t\t\tvalue=\"4.1.10\"\/>"

或者,您可以使用不同的字符而不是斜杠作为分隔符,例如#

sed -i -e "s#$ACTUAL_VERSION#$NEW_VERSION#g" buildSIM.xml

答案 1 :(得分:1)

好悲伤,只需使用awk,不要担心所有这些废话:

$ cat file
        <property name="systemVersionDsvTes"                            value="4.1.9"/>

$ ACTUAL_VERSION='\t<property name="systemVersionDsvTes"\t\t\t\tvalue="4.1.9"/>'

$ NEW_VERSION='\t<property name="systemVersionDsvTes"\t\t\t\tvalue="4.1.10"/>'  

$ awk -v act="$ACTUAL_VERSION" -v new="$NEW_VERSION" '{gsub(act,new)}1' file   
        <property name="systemVersionDsvTes"                            value="4.1.10"/>

实际上,您可能想要使用您采用的任何方法来转义ACTUAL_VERSION中的值中的“。”,因为它们匹配任何字符而不是文字“。”。或者,在awk中,您可以更改为使用字符串比较而不是RE比较:

$ awk -v act="$ACTUAL_VERSION" -v new="$NEW_VERSION" 'start=index($0,act) { $0=substr($0,1,start-1) new substr($0,start+length(act)) }1' file   
        <property name="systemVersionDsvTes"                            value="4.1.10"/>

与sed中没有相同的内容。