【发布时间】:2018-09-08 04:05:06
【问题描述】:
我有几个压缩的 xml 文件,其中包含存储在 Trans xml 标记中的事务。其中一些交易(不是全部!)包含<customer> xml 标签,其中包含custnumber xml 标签。我需要在 xml 文件中匿名化此客户编号,以便将 xml 文件用于开发目的。 xml的结构是这样的:
<transactions>
<trans>
...
<customer>
...
<customer_custnumber>123456789</customer_custnumber>
...
</customer>
...
</tran>
</transactions>
由于我的下游流程,我需要在散列时保留客户编号的最大长度。为此,我使用 java 编写了一个工具,该工具将客户编号散列为特定数字范围内的唯一散列。
我的第一种方法是使用从 xml 文件中读取所有客户编号,并在每次出现时调用我的哈希工具。这需要很长时间,因为我每个文件调用 java 工具 5000 次,导致每个文件的运行时间为 5-6 分钟(我每天有超过 40 个文件)。
我的第二个方法是使用 zgrep 和 awk 按照它们在 xml 文件中出现的顺序提取所有客户编号,将它们写入文本文件并运行我的 java 工具来散列文件的每一行。这明显更快,因为 5000 个数字只需要几秒钟。但现在我的问题是用文本文件中的散列值替换客户编号的原始值。我知道它们是有序的,所以 xml 文件中的第一次出现与文本文件中的第一个哈希值有关,依此类推。但是我现在如何替换它?
这是我当前的代码:
#!/bin/bash
tempFile=cardNumber_tmp.txt
hashedTempFile=hashed_cardNumber_tmp.txt
for file in ${DIR_SRC}/input.xml.zip ; do
declare listOfIds
listOfIds=$(zgrep "<customer_custnumber>" $file | awk -F">" '{print $2}' | awk -F"<" '{print $1}')
# $listOfIds contains all Ids separated whitespaces
# use tr to replace whitespace with newline
echo $listOfIds | tr " " "\n" > ${DIR_TEMP}/${tempFile}
# call HashCustNumber.jar for tempFile with type customer
java -jar HashCustNumber.jar "${DIR_TEMP}/${tempFile}" "customer"
# HashCustNumber.jar writes result into $hashedTempFile
declare -a arr
readarray -t arr < "${DIR_TEMP}/${hashedTempFile}"
# Array arr contains Hashes without newline
# ??
done
# delete tempFiles
rm ${DIR_TEMP}/${tempFile}
rm ${DIR_TEMP}/${hashedTempFile}
我还读到我不应该使用 sed 或 awk 从 xml 文件中提取数据,并且我无法使用 xmlstarlet,因为它没有安装在我的公司服务器上。任何想法如何以不涉及散列程序的数千次调用的方式将值替换为散列值?
【问题讨论】:
-
我可以假设客户编号是唯一的吗?然后将您的 java 输出稍微修改为:
customer-number:hash_value,每行一个。然后循环这些行,剪切:并使用 sed 或 awk 将客户编号替换为 has_value。是的,在处理 XML 时最好不要使用这些,但如果您无法访问 XML 解析器工具,那么这是您能做的最好的事情。但是,如果您对 Java “流利”,那为什么不使用 Java 做所有事情呢? XML 解析器存在于 Java 中,对您来说可能更简单。