我曾尝试将grep
加倍为sed
,但sed
忽略了已过滤的行。
我有一个文件:
<address domain='0x000' bus='0x71' slot='0x00' function='0x0' />
<address domain='0x000' bus='0x71' slot='0x00' function='0x1' />
<address domain='0x000' bus='0x71' slot='0x00' function='0x2' />
<address type='obo' domain='0x000' bus='0x71' slot='0x0c' function='0x0' />
<address domain='0x000' bus='0xdt' slot='0x00' function='0x0' />
<address type='obo' domain='0x000' bus='0x71' slot='0x01' function='0x0' />
<address domain='0x000' bus='0xdt' slot='0x00' function='0x1' />
我想把重点放在address domain
的行上,过滤成function=0x0
的行。。。最后只更改了bus IDs
例如:如果我试图用0xdt
和函数0x0
更新所有busses
,那么用LABEL_1,最终结果会是。。。
<address domain='0x000' bus='0x71' slot='0x00' function='0x0' />
<address domain='0x000' bus='0x71' slot='0x00' function='0x1' />
<address domain='0x000' bus='0x71' slot='0x00' function='0x2' />
<address type='obo' domain='0x000' bus='0x71' slot='0x0c' function='0x0' />
<address domain='0x000' bus='LABEL_1' slot='0x00' function='0x0' />
<address type='obo' domain='0x000' bus='0x71' slot='0x01' function='0x0' />
<address domain='0x000' bus='LABEL_1' slot='0x00' function='0x1' />
问题是,当有这么多行具有重复字段时,很难将重点放在特定行上。我能够将两次grep到我想要的过滤器中,但不知道如何更改想要的字符串并保存到同一个文件中。
感谢您的指导。
由于它看起来像一个XML文件,因此可以使用xmllint
和XPath
正确完成
获取匹配节点的计数
xmllint --xpath 'count(//address[@function="0x0" and @bus="0xdt"])' test.xml
更改第一个找到的节点的值,然后使用count
迭代其余节点
(printf 'cd //address[@function="0x0" and @bus="0xdt"][%d]/@busn' 1; echo -e 'set LABEL_1nsavenbye') | xmllint --shell test.xml
bus > set LABEL_1
bus > save
bus > bye
请确保备份该文件。
建议一行awk
脚本:
awk '/address domain=/ && /bus='0xdt'/ && /function='0x0'/{sub("bus='0xdt'","bus='LABEL_1'")}1' input.txt
输出:
<address domain='0x000' bus='0x71' slot='0x00' function='0x0' />
<address domain='0x000' bus='0x71' slot='0x00' function='0x1' />
<address domain='0x000' bus='0x71' slot='0x00' function='0x2' />
<address type='obo' domain='0x000' bus='0x71' slot='0x0c' function='0x0' />
<address domain='0x000' bus='LABEL_1' slot='0x00' function='0x0' />
<address type='obo' domain='0x000' bus='0x71' slot='0x01' function='0x0' />
<address domain='0x000' bus='0xdt' slot='0x00' function='0x1' />
请注意,输出与给定的示例不匹配!!!
awk
脚本说明:
/address domain=/ # for a line matching RegExp /address domain=/
&& /bus='0xdt'/ # and matching matching RegExp /bus='0xdt'/
&& /function='0x0'/ { # and matching matching RegExp /function='0x0'/
sub("bus='0xdt'","bus='LABEL_1'"); # substitute RegExp /bus='0xdt'/ with "bus='LABEL_1'"
}
{print} # print each line