将一个文件(CSV)的列值复制到另一个XML格式的文件

时间:2017-11-26 06:31:30

标签: xml shell awk sed grep

我有数百万的数据,我试图将列值从一个file1插入另一个file2。 File1是CSV文件(" |"管道分离)的数据如下

1.1.1.1|LM
1.2.3.4|MV
10.113.45.123|MN

和File2是基于XML格式的文件:

<xml version="01">
        <raw_data>
                <Add>
                        <value IP="" META=""></value>
                        <value IP="" META=""></value>
                        <value IP="" META=""></value>
                </Add>
        </raw_data>
</xml>

这里我想将FILE1的第1列复制到FILE2(IP),将第2列复制到FILE2的META,如下所示:

    <xml version="01">
        <raw_data>
                <Add>
                        <value IP="1.1.1.1" META="LM"></value>
                        <value IP="1.2.3.4" META="MV"></value>
                        <value IP="10.113.45.123" META="MN"></value>
                </Add>
        </raw_data>
   </xml>

所以最后输出应如上所示。

4 个答案:

答案 0 :(得分:2)

使用callbacks - name: send key to remote deploy user copy: src=/home/vagrant/code/id_rsa dest=home/priv_key owner=root group=root mode=0600 - name: Clone repo git: repo: git@github.ncsu.edu:rcoutin/BOT.git dest: home/app key_file: ../priv_key accept_hostkey: yes force: yes become: no 更新多个属性:

bash

输出到file2.xml:

xmlstarlet

更新以执行变量declare -i c=1 # set integer attribute while IFS="|" read -r ip meta; do xmlstarlet edit -L --omit-decl \ --update "//raw_data/Add/value[$c]/@IP" --value "$ip" \ --update "//raw_data/Add/value[$c]/@META" --value "$meta" file2.xml c=c+1 done < file1 中的所有更改:

<xml version="01">
  <raw_data>
    <Add>
      <value IP="1.1.1.1" META="LM"/>
      <value IP="1.2.3.4" META="MV"/>
      <value IP="10.113.45.123" META="MN"/>
    </Add>
  </raw_data>
</xml>

输出到标准输出:

$file

请参阅:declare -i c=1 # set integer attribute file=$(cat file2.xml) while IFS="|" read -r ip meta; do file_mod=$( xmlstarlet edit --omit-decl \ --update "//raw_data/Add/value[$c]/@IP" --value "$ip" \ --update "//raw_data/Add/value[$c]/@META" --value "$meta" <<< "$file" ) file="$file_mod" c=c+1 done < file1 echo "$file"

答案 1 :(得分:0)

你绝对应该使用Cyrus发布的答案,在阅读/编写json和xml时使用标准工具是很好的。

但是,如果您仍想使用通用linux命令,则可以使用awk来实现相同的目标:

$ cat file 
1.1.1.1|LM
1.2.3.4|MV
10.113.45.123|MN
$ awk -F\| 'BEGIN{printf "<xml version=\"01\">\n<raw_data>\n<Add>\n"} {printf "<value IP=\"%s\" META=\"%s\"></value>\n", $1, $2} END {printf "</Add>\n</raw_data>\n</xml>\n"}' file
<xml version="01">
<raw_data>
<Add>
<value IP="1.1.1.1" META="LM"></value>
<value IP="1.2.3.4" META="MV"></value>
<value IP="10.113.45.123" META="MN"></value>
</Add>
</raw_data>
</xml>
$

答案 2 :(得分:0)

如果xmlstartlet花了很长时间来完成这项工作,你可以尝试考虑使用perl,但我怀疑它会做得更好。

# cat list
1.1.1.1|LM
1.2.3.4|MV
10.113.45.123|MN
# perl -ane 's/^([^|]+)\|([^\s]+)/<value IP="\1" META="\2"><\/value>/;\
  s/^/<xml version="01">\n<raw_data>\n<Add>\n/ if $. == 1;\
  s/$/\n<\/Add>\n<\/raw_data>\n<\/xml>/ if eof;\
  print' list
<xml version="01">
<raw_data>
<Add>
<value IP="1.1.1.1" META="LM"></value>
<value IP="1.2.3.4" META="MV"></value>
<value IP="10.113.45.123" META="MN"></value>
</Add>
</raw_data>
</xml>

注意:不是最简单的perl你可以得到但仍然。确认推荐的做法,例如不硬编码新行。但此刻我对此有点懒惰。您还可以考虑使用[ Tidy ]

答案 3 :(得分:0)

扩展 awk + xmlstarlet 合作:

awk -F'|' -v cmd='xmlstarlet ed -L -u "//Add/value[%d]/@IP" -v "%s" -u "//Add/value[%d]/@META" -v "%s" file2.xml' \
'system(sprintf(cmd, NR, $1, NR, $2))' file1.csv

最终file2.xml内容:

<?xml version="1.0"?>
<xml version="01">
  <raw_data>
    <Add>
      <value IP="1.1.1.1" META="LM"/>
      <value IP="1.2.3.4" META="MV"/>
      <value IP="10.113.45.123" META="MN"/>
    </Add>
  </raw_data>
</xml>