我有数百万的数据,我试图将列值从一个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>
所以最后输出应如上所示。
答案 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>