假设我有以下示例字符串:
<ETH0_IP><![CDATA[10.0.100.10]]></ETH0_IP>
我想提炼这第一个数字 和这知识产权采用以下格式:
0 10.0.100.10
我确实知道如何提取第一个 ( sed 's@^[^0-255]*\([0-255]\+\).*@\1@'
) 数字和 IP ( grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
),但是当时一个我想知道我是否可以只用一行实现它
答案1
如果您需要所有(整数)数字和所有 IP(v4) 地址,请使用 grep 向正则表达式添加替换:
... | grep -oE '[0-9]+|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
这将每行打印一个值,当然也会0
从ETH0
末尾捕获 。
如果您只需要输入行中包含与上述类似结构(而不是其他结构)的数字和 IP,您可以使用例如 sed:
... | sed -nEe 's,.*<ETH([0-9]+)_IP><!\[CDATA\[([0-9.]+)\]\]></ETH[0-9]+_IP>.*,\1 \2,p'
\1
并对应于括号中的第一组和第二组,为了清晰和懒惰,\2
我将 IP 与此处进行了匹配。[0-9.]+
或者在 Perl 中类似:
... | perl -ne 'print "$1 $2\n" if m,<ETH([0-9]+)_IP><!\[CDATA\[([0-9.]+)\]\]></ETH[0-9]+_IP>,'
答案2
将所有非数字(而不是“.”)字符替换为空格,然后可以打印出第一列和第二列:
echo '<ETH0_IP><![CDATA[10.0.100.10]]></ETH0_IP>' | \
sed -re 's;[^0-9.]; ;g' | \
awk '{print $1,$2}'
输出:
0 10.0.100.10
ps:如果你有“.”,你必须让它变得更复杂。其他地方,而不仅仅是 IP 中。
答案3
使用xq
(来自https://kislyuk.github.io/yq/),并假设输入实际上是问题中的单个 XML 节点:
xq -r 'to_entries[] | [ (.key|ltrimstr("ETH")|rtrimstr("_IP")), .value ] | @tsv' file.xml
这会将 XML 文档转换为 JSON,然后通过ETH
从开头和_IP
结尾剥离来提取标签名称的剩余部分。还会提取 IP 地址,并将两个结果值作为制表符分隔列表输出。
ltrimstr()
and调用可能会被orrtrimstr()
替换,这会删除标签名称中的所有非数字。gsub("[^[:digit:]]"; ""))
gsub("\\D"; ""))
中间 JSON 文档看起来像
{
"ETH0_IP": "10.0.100.10"
}
...最后的输出将是
0 10.0.100.10