Bash 如何从文件中多次出现的两个字符串之间提取值

Bash 如何从文件中多次出现的两个字符串之间提取值,bash,shell,awk,sed,grep,Bash,Shell,Awk,Sed,Grep,我试图从两个字符串之间提取值,并在每个结果中换行。然后我希望将其与以相同方式提取的同一文档中的另一个值结合起来。问题是此文件中没有换行符,而且它相当大。下面是该文件的一个示例 <ID>47</ID><DATACENTER_ID>36</DATACENTER_ID><DNS_NAME>myhost.domain.local</DNS_NAME> <IP_ADDRESS>10.0.0.1</IP_AD

我试图从两个字符串之间提取值,并在每个结果中换行。然后我希望将其与以相同方式提取的同一文档中的另一个值结合起来。问题是此文件中没有换行符,而且它相当大。下面是该文件的一个示例

<ID>47</ID><DATACENTER_ID>36</DATACENTER_ID><DNS_NAME>myhost.domain.local</DNS_NAME>      <IP_ADDRESS>10.0.0.1</IP_ADDRESS><ID>60</ID><DATACENTER_ID>36</DATACENTER_ID><DNS_NAME>yourhost.domain.local</DNS_NAME><IP_ADDRESS>10.0.0.2</IP_ADDRESS>

到目前为止,我最接近的尝试是使用grep创建变量,但我似乎无法将它们格式化为表。我对脚本也很陌生,所以请原谅我的无知。

如果您的grep支持
-p
-Perl regexp
),那么您可以自由使用下面的正则表达式

$ grep -oP '<ID>\K[^<>]*(?=</ID>)|<DNS_NAME>\K[^<>]*(?=</DNS_NAME>)' file | sed 'N;s/\n/-----/g'
47-----myhost.domain.local
60-----yourhost.domain.local
$grep-oP'\K[^]*(?=)|\K[^]*(?=)'文件| sed'N;s/\n/----/g'
47----myhost.domain.local
60----yourhost.domain.local
\K
从打印中丢弃先前匹配的字符


(?=…)
posiitve先行断言,该断言断言匹配发生的位置。它不会消耗任何字符。

这里有一个
gnu awk
(在
RS
中处理多个字符)来获取您的数据:

awk -v RS="<ID>" -F"<|>" 'NR>1 {print $1"-----"$9}' file
47-----myhost.domain.local
60-----yourhost.domain.local
awk-vrs=“”-F“'NR>1{print$1”--“$9}”文件
47----myhost.domain.local
60----yourhost.domain.local

XML解析应该避免使用基本的shell实用程序,而应该使用专用的XML解析器。良好地使用
grep-o
!我唯一好奇的是,从效率的角度来看,
grep/sed
组合与双表达式
sed
(例如
sed-e exp1 exp2文件
)解决方案相比如何。不管怎样,回答得很好。谢谢阿维纳什,太好了!这也很方便!非常感谢你,乔顿。
awk -v RS="<ID>" -F"<|>" 'NR>1 {print $1"-----"$9}' file
47-----myhost.domain.local
60-----yourhost.domain.local