Reputation: 1
I need to use awk to increase the version number by one in the line after a unique string.
Original:
<key>UniqueKey</key>
<string>100</string>
Desired output
<key>UniqueKey</key>
<string>101</string>
Unfortunately "string" is not unique in the file, so I have to modify the line after the unique "key" string. I need to take the number, whatever it may be, and increase it by one. The command will be running in a virtual workspace that gets deleted each time, so a simple awk command would be preferred.
Upvotes: 0
Views: 104
Reputation: 67467
$ awk -F'[<>]' '$3=="UniqueKey"{n=NR}
n && NR==n+1 && $2=="string"{sub($3,$3+1)}1' file
<key>UniqueKey</key>
<string>101</string>
Upvotes: 2
Reputation: 203334
$ awk -F'[<>]' '$2=="string" && p3=="UniqueKey" { sub(/>[^<]+/,">"$3+1) } {p3=$3} 1' file
<key>UniqueKey</key>
<string>101</string>
Upvotes: 0
Reputation: 26471
This looks remarkably like an XML file. It is strongly recommended to use XML-related tools for this job such as xmlstarlet
.
Assuming a given input file of the form :
<header>
<node>
<key>UniqueKey</key>
<foo />
<string>100</string>
</node>
<node>
<key>UniqueKey</key>
<string>101</string>
<string>200</string>
</node>
</header>
Then the following command will update as requested :
$ xmlstarlet ed -u '//key[text()="UniqueKey"]/following-sibling::string[1]' \
-x '(text()+1)' file.xml
This does the following :
ed
: enter editing mode-u <xpath>
: update the nodes matched by xpath
//key
: select any node with name key
//key[text()="UniqueKey"]
: select any node with the name key
and value "UniqueKey"
//key[text()="UniqueKey"]/following-sibling::string
: pick the first 'string' siblings of key
that follows key
-x '(text()+1)'
: update the selected nodes value by the expression text()+1
The output is then given by :
<?xml version="1.0"?>
<header>
<node>
<key>UniqueKey</key>
<foo/>
<string>101</string> # change
</node>
<node>
<key>UniqueKey</key>
<string>102</string> # change
<string>200</string> # no change
</node>
</header>
Or if it realy has to be the next node, then you need to play a trick with concat
and substring
as xpath-1.0 does not have if conditions. More details here
$ xmlstarlet ed -u '//key[text()="UniqueKey"]/following-sibling::*[1]' \
-x 'substring(text()+1,1,number(name()="string")*string-length(text()+1))' file.xml
<?xml version="1.0"?>
<header>
<node>
<key>UniqueKey</key>
<foo/>
<string>100</string> # no change
</node>
<node>
<key>UniqueKey</key>
<string>102</string> # change
<string>200</string> # no change
</node>
</header>
Upvotes: 0