首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用shell命令将特定的XML文档元素复制到另一个XML文档中。

使用shell命令将特定的XML文档元素复制到另一个XML文档中。
EN

Stack Overflow用户
提问于 2020-05-07 21:15:58
回答 1查看 946关注 0票数 2

我正在通过shell脚本在AWS EMR上安装Kylin。我有一个xml文件,其内容如下,需要将特定的文档元素复制到另一个xml文件中。这是在运行安装shell脚本时使用shell命令自动执行的手动步骤。

/etc/hbase/conf/hbase-site.xml

代码语言:javascript
复制
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
  </property>

  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>ip-nn-nn-nn-nn.ec2.internal</value>
  </property>

  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://ip-nn-nn-nn-nn.ec2.internal:xxxx/user/hbase</value>
  </property>

  <property>
    <name>dfs.support.append</name>
    <value>true</value>
  </property>

  <property>
    <name>hbase.rest.port</name>
    <value>xxxx</value>
  </property>
</configuration>

我需要将hbase.zookeeper.quorum属性从/etc/hbase/conf/hbase-site.xml复制到$kylin_HOME/conf/kylin_job_con.xml,如下所示:

代码语言:javascript
复制
<property>
  <name>hbase.zookeeper.quorum</name>
  <value>ip-nn-nn-nn-nn.ec2.internal</value>
</property>

注意:$kylin_HOME/conf/kylin_job_con.xml中已经包含了其他一些数据。

需要将输出复制到目标文件。

目标文件“$kylin_HOME/conf/kylin_job_con.xml”如下所示:

代码语言:javascript
复制
<configuration>

    <property>
        <name>mapreduce.job.split.metainfo.maxsize</name>
        <value>-1</value>
        <description>The maximum permissible size of the split metainfo file.
            The JobTracker won't attempt to read split metainfo files bigger than
            the configured value. No limits if set to -1.
        </description>
    </property>

    <property>
        <name>mapreduce.map.output.compress</name>
        <value>true</value>
        <description>Compress map outputs</description>
    </property>

    <property>
        <name>mapreduce.output.fileoutputformat.compress</name>
        <value>true</value>
        <description>Compress the output of a MapReduce job</description>
    </property>

    <property>
        <name>mapreduce.output.fileoutputformat.compress.codec</name>
        <value>org.apache.hadoop.io.compress.SnappyCodec</value>
        <description>The compression codec to use for job outputs
        </description>
    </property>

    <property>
        <name>mapreduce.output.fileoutputformat.compress.type</name>
        <value>BLOCK</value>
        <description>The compression type to use for job outputs</description>
    </property>

    <property>
        <name>mapreduce.job.max.split.locations</name>
        <value>xxxx</value>
        <description>No description</description>
    </property>

    <property>
        <name>dfs.replication</name>
        <value>xxx</value>
        <description>Block replication</description>
    </property>

    <property>
        <name>mapreduce.task.timeout</name>
        <value>xxxx</value>
        <description>Set task timeout to 1 hour</description>
    </property>

</configuration>

预期产出:

代码语言:javascript
复制
<configuration>

    <property>
        <name>mapreduce.job.split.metainfo.maxsize</name>
        <value>-1</value>
        <description>The maximum permissible size of the split metainfo file.
            The JobTracker won't attempt to read split metainfo files bigger than
            the configured value. No limits if set to -1.
        </description>
    </property>

    <property>
        ---------
        ---------
        ---------
    </property>

    <property>
        ---------
        ---------
        ---------
    </property>

    <property>
        ---------
        ---------
        ---------
    </property>

    <property>
        <name>hbase.zookeeper.quorum</name>
        <value>ip-nn-nn-nn-nn.ec2.internal</value>
    </property>

</configuration>

是否有任何shell命令可以从上面的xml文件中获取特定的文档元素并自动将其复制到另一个xml文件中。

我试过以下命令:

代码语言:javascript
复制
awk 'NR == FNR { if(FNR >= 30 && FNR <= 33) { patch = patch $0 ORS }; next } FNR == 88 { $0 = patch $0 } 1' /etc/hbase/conf/hbase-site.xml $KYLIN_HOME/conf/kylin_job_conf.xml > $KYLIN_HOME/conf/kylin_job_conf.xml

上面的命令不适用于me.can --有人帮我解决这个问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-07 22:15:17

尝试使用RegEx‘’es查询XML文件很少是个好主意。

总是喜欢使用XML解析器!

这样你就可以用xmlstarlet完成你的任务了。这是一个可以从输入(“input.xml”)命令中获取所需数据的单一程序:

代码语言:javascript
复制
xmlstarlet sel -t -c "/configuration/property[name='hbase.zookeeper.quorum']" input.xml

其产出是:

代码语言:javascript
复制
<property>
  <name>hbase.zookeeper.quorum</name>
  <value>ip-nn-nn-nn-nn.ec2.internal</value>
</property>

如果计算机上没有安装小星,请执行以下操作

代码语言:javascript
复制
sudo apt-get -y install xmlstarlet

命令行选项如下:

  • sel:选择数据或查询XML文档(XPATH等)
  • -t:模板模式:为模板解释以下命令
  • -c:打印以下XPATH表达式的副本

现在,在第二步中,将结果XML复制到目标文件中。这在答案是:“如何使用xmlstarlet添加多个子节点的xml文件?”中描述的方法中是可能的。

应用于您的示例,下面的命令行实现了您想要的结果:

代码语言:javascript
复制
xmlstarlet ed -a "/configuration/property[last()]" -t elem -n property \
-v "$(xmlstarlet sel -t -c "/configuration/property[name='hbase.zookeeper.quorum']/*" input.xml)" \
target.xml | xmlstarlet unesc | xmlstarlet fo > new_target.xml

new_target.xml的结果是

代码语言:javascript
复制
<?xml version="1.0"?>
<configuration>
  <property>
    <name>mapreduce.job.split.metainfo.maxsize</name>
    <value>-1</value>
    <description>The maximum permissible size of the split metainfo file.
            The JobTracker won't attempt to read split metainfo files bigger than
            the configured value. No limits if set to -1.
        </description>
  </property>
  <property>
    <name>mapreduce.map.output.compress</name>
    <value>true</value>
    <description>Compress map outputs</description>
  </property>

  ...

  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>ip-nn-nn-nn-nn.ec2.internal</value>
  </property>
</configuration>

但是,这种方法有一个缺点:它解除目标文件中的所有实体(使用xmlstarlet unesc命令),因此像&amp;这样的实体将被转换为&.这可能会破坏一切。

如果这是一个问题,请考虑使用带有完整XSLT处理器和样式表的解决方案。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61667880

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档