我正在使用firewalld xml文件,看起来像:
<?xml version="1.0" encoding="utf-8"?>
<zone>
<short>Public</short>
<description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<service name="ssh"></service>
<service name="dhcpv6-client"></service>
<service name="cockpit"></service>
<service name="https"></service>
<service name="http"></service>
<port port="5000" protocol="tcp"></port>
<port port="5001" protocol="tcp"></port>
<port port="9999" protocol="tcp"></port>
<port port="9998" protocol="tcp"></port>
<rule>
<protocol value="vrrp"></protocol>
<accept></accept>
</rule>
</zone>
使用 yq 我想向其中添加几个新的 tcp 端口,对它们进行排序并确保它们是唯一的
kislyuk/yq 提供
xq
命令,可用于使用 jq
语法操作 XML 文件。
对于这种情况,只需将另一个对象(包装到数组中)附加到现有数组,然后对其应用
unique
(这也会对项目进行排序)。请注意,端口号作为字符串进行处理,因此为了按数字顺序对它们进行排序,请使用 tonumber
进行转换以进行比较。最后,-x
标志会将结果转换回 XML。
xq -x '.zone.port |= (
. + [{"@port": "993", "@protocol": "tcp"}]
| unique_by(."@port" | tonumber)
)' file.xml
<zone>
<short>Public</short>
<description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<service name="ssh"></service>
<service name="dhcpv6-client"></service>
<service name="cockpit"></service>
<service name="https"></service>
<service name="http"></service>
<port port="993" protocol="tcp"></port>
<port port="5000" protocol="tcp"></port>
<port port="5001" protocol="tcp"></port>
<port port="9998" protocol="tcp"></port>
<port port="9999" protocol="tcp"></port>
<rule>
<protocol value="vrrp"></protocol>
<accept></accept>
</rule>
</zone>
如果您想一次添加多个条目,请考虑使用
--args
将它们作为命令行参数读取(自 jq 1.6 起可用):
xq -x '.zone.port |= (
. + [$ARGS.positional | _nwise(2) | {"@port": first, "@protocol": last}]
| unique_by(."@port" | tonumber)
)' file.xml --args 6543 tcp 210 udp
<zone>
<short>Public</short>
<description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<service name="ssh"></service>
<service name="dhcpv6-client"></service>
<service name="cockpit"></service>
<service name="https"></service>
<service name="http"></service>
<port port="210" protocol="udp"></port>
<port port="5000" protocol="tcp"></port>
<port port="5001" protocol="tcp"></port>
<port port="6543" protocol="tcp"></port>
<port port="9998" protocol="tcp"></port>
<port port="9999" protocol="tcp"></port>
<rule>
<protocol value="vrrp"></protocol>
<accept></accept>
</rule>
</zone>
pmf 的答案是正确的,但是当我问我的问题时,我提到了另一个 yq 可执行文件(mikefarah/yq)。这个没有安装 xq,但是有专门的 xml 解析语法。而且没有 tonumber 转换,所以正确的语法是:
yq -p xml -o xml --xml-keep-namespace '.zone.port |= ( . + [{"+port":"8500","+protocol":"tcp"}] | sort_by(."+port") | unique_by(."+port") )' /etc/firewalld/zones/public.xml