使用shell脚本获取多行XML中的标签值

7 浏览
0 Comments

使用shell脚本获取多行XML中的标签值

我有一个如下的xml文件:



  
    
    
  

我只想从每个moduleid中提取dataPath的值。

我之前使用了以下命令:

`grep 'id2' file | grep -ioPm1 "(?<=DataPath=)[^ ]+"`

这个命令只能从第一个模块id中获得结果,而无法获取第二个模块id的结果,因为第二个模块的内容分布在多行中。

如何使用shell脚本实现这个功能?

期望的输出是:如果我想获取id1模块的datapath,则应该得到

/my/file/path

如果是第二个模块id,比如id2,则应该得到用逗号分隔的datapath

/my/file/path, /my/file/path

或者我的第二个方法是只替换之间的换行符,然后再使用grep命令。

0
0 Comments

问题:如何使用Shell脚本从多行XML中获取标签值?

原因:Bash本身不适合解析XML。Bash FAQ中明确指出不要使用sed、awk、grep等工具来提取XML文件中的数据。

解决方法:

1. 如果一定要使用Shell脚本,可以使用专门的XML命令行工具,比如XMLStarlet或xsltproc。如果尚未安装XML Starlet,请参考下载信息。

2. 使用以下xslt模板来实现对源XML和所需输出的处理。

template.xsl的内容如下:

,

,

,

然后运行以下命令之一:

- 使用XML Starlet命令:

$ xml tr /path/to/template.xsl /path/to/input.xml

- 或使用xsltproc命令:

$ xsltproc /path/to/template.xsl /path/to/input.xml

其中,上述命令中的`/path/to/template.xsl`和`/path/to/input.xml`应替换为实际文件路径。

以上命令将转换输入的`input.xml`文件并打印出所需的结果。

示例:

假设有以下`input.xml`文件:



  
  
    
      
      
    
  
  
    
      
      
    
  
  
  
  
  
    
      
    
  
  

运行上述命令后,将输出以下结果:

/abc/def/1
/abc/def/2, /abc/def/3
/abc/def/4, /abc/def/5, /abc/def/6
/abc/def/7
/abc/def/8

附加说明:

如果不想使用单独的.xsl文件,可以将上述XSLT模板嵌入到Shell脚本中,如下所示:

#!/usr/bin/env bash
xslt() {
cat <

  
  
    
  
  
    
      
        
        

      
      
        
          
          
            , 
          
        
        

      
      
        
        , 
        
          
          
            , 
          
        
        

      
    
  

EOX
}
# 1. 使用XML Startlet
xml tr <(xslt) /path/to/input.xml
# 2. 或使用xsltproc
xsltproc <(xslt) - 

其中,脚本中的`/path/to/input.xml`应替换为实际文件路径。

0
0 Comments

问题的出现原因:

这段内容是在回答一个关于如何在多行XML中获取标签值的问题。问题的原因是,使用grep命令只能获取匹配到的第一行结果,无法获取到所有匹配的结果。

解决方法:

回答者建议不要使用grep这样的逐行工具来解析XML,而是使用更方便的工具,比如xmlstarlet。他给出了两个使用xmlstarlet的命令示例,可以获取到所有匹配的标签值。其中一个命令会在没有匹配到带有dataPath属性的元素时打印一个空行。

然而,回答者认为问题的提问者可能希望将每个Module元素节点相关的dataPath属性值分组并以逗号分隔打印出来,而不是每个属性值都打印在单独的一行。他认为换行符应该作为每个Module元素节点的分隔符。

因此,问题的解决方法是使用xmlstarlet工具,并根据需求选择合适的命令参数来获取所需的标签值。

0