打印包含 的特定模式之间的字符

打印包含  的特定模式之间的字符

我请求你的帮助。

我查阅了很多资料,并使用 awk 和 sed 做了一些测试,但我无法让它工作。下面是配置文件的片段,我可以通过 grep 获得输出,但不是我需要的方式。

> file.txt
> 
> "<property>name="DBName"><value>ABC</value>name="DBName"><value>DEF</value></property>
> 
> cat file.xml | grep -o -P '.name="DBName"><value>.{0,20}'
> name="DBName"><value>ABC</value>
> name="DBName"><value>DEF</value></propert

期望的输出是:

ABC
DEF

谢谢你的帮助。

和我

答案1

如果(巨大的,巨大的“如果”)你的文件实际上只有非常简单的情况,你想要精确的string<value>后跟一些非<字符,然后是,因此您的问题可以表述为“获取在每次出现及其后的第一个</value>出现之间找到的简单的非换行符字符串”,然后您可以执行以下操作(使用 GNU ) :<value><grep

grep -oP '<value>\K[^<]+' file

当然,即使稍有不同,这也会失败。例如,如果您有多行值,或者值标记可以具有类似<value foo=bar>或 的内容,则可以在任意数量的其他完全有效的 XML 情况下进行。正确的方法©是使用 XM: 解析器。您可能想查看xmllint或者XML小星除其他外。

答案2

如果您的所有输入看起来与您发布的一行示例输入完全相同:

$ cat file
"<property>name="DBName"><value>ABC</value>name="DBName"><value>DEF</value></property>

然后使用任何 awk:

$ awk -F'[<>]+' '{for (i=5; i<=NF; i+=4) print $i}' file
ABC
DEF

但是,与任何其他不使用 XML 解析器的解决方案一样,它很脆弱。

答案3

使用XMLStarlet

XML 文件取自答案

<config>
 <property name="DBName"><value>ABC</value></property>
 <property name="DBName" year="2023"><value>DEF</value></property>
 <property name="SystemName"><value>s70</value></property>
</config>
$ xmlstarlet select -t -v '//value' --nl ex.xml
ABC
DEF
s70

$ xmlstarlet select -t -m '//property[@name="DBName"]' -v 'value' --nl ex.xml
ABC
DEF

使用 awk:

$ awk -v pat1="<value>" -v pat2="</value>" '
   {
       while (match($0, pat1)){ 
           $0=substr($0,RSTART+RLENGTH);
           if (match($0, pat2)) print substr($0,1,RSTART-1)
       }
   }
'

和解决awk方案pcregrep适用于该问题,但在很多情况下可能会失败。

$ pcregrep -o1 '<value>(.*?)</value>'

答案4

如果您有一个格式良好的 XML 输入,例如我们

<config>
 <property name="DBName"><value>ABC</value></property>
 <property name="DBName" year="2023"><value>DEF</value></property>
 <property name="SystemName"><value>s70</value></property>
</config>

您可以使用 XML 感知工具,并使用 Xpath(或类似工具)来选择要提取的部分。示例为希德尔:

## 1) get all values:
$ xidel -e "//value" ex.xml 
ABC
DEF
s70
## 2) get the values inside "property" with attribute "name" "DBname"
$ xidel -e "//property[@name='DBname']/value" ex.xml 
ABC
DEF

相关内容