我每天都有xml报告,我正在尝试查看每个报告并查找购买日期,并确定它是否至少比文件日期早一年。如果是这样,我将文件的名称和购买日期写入日志。问题是性能真的非常糟糕。
#!/bin/bash
for file in *xml ; do
fileDate=`echo ${file} | cut -c 18-35 | sed 's/.xml//'`
fileDateSeconds=`date --date="${fileDate}" +"%s"`
awk '/PurchaseDate/ {print}' ${file} >> /tmp/yamExport/tempFile.txt
cat /tmp/yamExport/tempFile.txt | while read input
do
lineDate=`echo ${input} | cut -c 15-24`
lineDateSeconds=`date --date="${lineDate}" +"%s"`
delta=`expr $fileDateSeconds - $lineDateSeconds`
if [ "$delta" -gt "31556926" ]
then
#echo "$file : $input"
echo "$file : $input" >> /tmp/yamExport/yamExportTimestamps2.log
fi
done
done
起初我只是逐行遍历整个文件
cat ${file} | while read input
do
if [[ "$input" =~ "PurchaseDate" ]]
then
但后来我确定使用awk快速抓取所有使用PurchaseDate的行并输出到临时文件然后循环更快(但仍然很慢)。如果有人对如何提高性能有任何建议,那将非常有帮助。我可以在类似于循环的awk语句的输出上操作吗?如果我能做到这一点,我认为性能要好得多。
感谢您的任何提示。
答案 0 :(得分:5)
将awk输出写入临时文件肯定会破坏您的性能。此外,您将附加到该临时文件,因此您正在处理每个后续xml文件的第一个xml文件的结果。
此代码最大限度地减少了您需要调用的外部进程数
for file in *xml ; do
fileDateSeconds=$(date --date="${file:17:18}" +"%s")
grep -F 'PurchaseDate' "$file" |
while read input; do
lineDateSeconds=$(date --date="${input:14:10}" +"%s")
if (( (fileDateSeconds - lineDateSeconds) > 31556926 )); then
echo "$file : $input"
fi
done
done > /tmp/yamExport/yamExportTimestamps2.log
我将awk
更改为grep
,这是查找文件中的行的更合适的工具。
将重定向移动到外部循环外部的输出文件应减少文件打开的次数。
答案 1 :(得分:1)
以下是一些想法:
#!/bin/bash
for file in *xml ; do
fileDate=`echo ${file} | cut -c 18-35 | sed 's/.xml//'`
fileDateSeconds=`date --date="${fileDate}" +"%s"`
grep PurchaseDate ${file} | while read input
do
lineDate=`echo ${input} | cut -c 15-24`
lineDateSeconds=`date --date="${lineDate}" +"%s"`
delta=$((fileDateSeconds - lineDateSeconds))
if [ "$delta" -gt "31556926" ]
then
echo "$file : $input"
fi
done
done > /tmp/yamExport/yamExportTimestamps2.log