gavlinski
gavlinski

Reputation: 43

Replace part of a line containing tabs

How can one replace a part of a line containing tabs (\t) with sed, awk, or any other?

The line

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

or

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

should be replaced to:

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

or

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

The value xxx can vary and there are one tab before property name and four tabs before value. This name-value pair is the only one from a xml file.

I tried with the following:

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

and that resulted in an error: sed: -e expression #1, character 65: Unknow option for command `s' (s///?)

Whats wrong with the expression? Using GNU sed.

Upvotes: 0

Views: 125

Answers (2)

Joni
Joni

Reputation: 111259

The error message Unknow option for command 's' (s///?) refers to the "options" that can be added to the substitute command after the third slash. These options include letters like g to replace all occurrences of the pattern rather than just the first one, or i to ignore letter case. It usually hints that the pattern or substitution includes extra slashes. To deal with slashes in the pattern or the substitution they have to be escaped, too:

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\"\/>"

Alternatively you can use a different character instead of a slash as the separator, for example #:

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

Upvotes: 1

Ed Morton
Ed Morton

Reputation: 203512

Good grief, just use awk and don't worry about all that sed nonsense:

$ 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"/>

In reality, you might want to escape the "."s in the value in ACTUAL_VERSION with whichever approach you adopt since they match any character rather than a literal ".". Alternatively, in awk you can change to using a string comparison rather than an RE comparison:

$ 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"/>

There is no equivalent to that in sed.

Upvotes: 1

Related Questions