我的应用程序基于输入 XML 进行处理,处理输入文件并在处理后将状态添加到 status_file.txt。
我正在编写一个脚本来识别每个 XML 文件的最后处理日期并将其作为另一个脚本的输入提供。
我部署了两种类型的 XML:
-
- 支持周末处理 (
test2.xml
)
- 支持周末处理 (
-
- 不支持周末处理。(
test1.xml
)
- 不支持周末处理。(
启用周末处理的示例 XML -test2.xml
<?xml version="1.0"?>
<Company>
<Employee>
<FirstName>Test</FirstName>
<ContactNo>1234567890</ContactNo>
<Address>
<WeekendProcessing>True</WeekendProcessing>
</Address>
</Employee>
</Company>
禁用周末处理的示例 XML -test1.xml
<?xml version="1.0"?>
<Company>
<Employee>
<FirstName>Test</FirstName>
<ContactNo>1234567890</ContactNo>
<Address>
<WeekendProcessing>False</WeekendProcessing>
</Address>
</Employee>
</Company>
样本status_file.txt
INPUT_NAME1,INPUT_NAME2,Procecessed_DATE
test1.xml,AAAA,BBBB,20201024
test1.xml,AAAA,CCCC,20201025
test2.xml,AAAA,BBBB,20201024
test1.xml,EFGH,IJKL,20201023
test1.xml,AAAA,BBBB,20201024
test2.xml,AAAA,CCCC,20201021
test1.xml,AAAA,BBBB,20201022
test2.xml,AAAA,BBBB,20201022
test1.xml,EFGH,IJKL,20201023
下面是我尝试获取 XML 最后处理日的命令。
LPD=$(cat status_file.txt | grep <XML_NAME> | awk -F "," '{print $NF}' | sort | uniq)
注意:这里的工作日是指工作日,从周一到周五
它适用于支持周末处理的 XML。但我陷入了识别不支持周末处理的 XML 的最后处理工作日的困境。注意:即使对于工作日,也会出现带有周末日期的 XML 条目。
另外:我无法使用 sort 和 tail -2 的逻辑,因为周末有时我们可能会得到超过 2 个条目。
预期结果:
# script <test1.xml> - I should get last processed weekday
O/p Required - 20201023
# script <test2.xml> - I should get last processed day either weekday/weekend
O/p Required - 20201025
答案1
借助 GNUawk
和一些帮助来xmllint
解析 xml。
#!/bin/bash
input_file="$1"
status_file="status_file.txt"
weekend="True"
weekend="$(xmllint --xpath "//WeekendProcessing/text()" "$1")"
awk -F, -v f="$input_file" -v weekend="$weekend" '
$1 == f && $NF > max {
if (weekend == "True") {
max = $NF
} else {
d = mktime(substr($NF,1,4)" "substr($NF,5,2)" "substr($NF,7)" 00 00 00")
if (strftime("%u",d) < 6) max = $NF
}
}
END {print max}
' "$status_file"
测试:
> bash test.sh test1.xml
20201023
> bash test.sh test2.xml
20201024
笔记:
我曾经通过单个路径选择来
xmllint
提取节点的文本值。WeekendProseccing
您可以将其替换为您最喜欢的从 xml 文件获取值的方式。我们不对行进行排序,我们解析一次文件,它也更快。我们不调用外部日期命令。对于
weekend="True"
,我们保留最大日期。否则,对于weekend="False"
,我们使用GNU awk 日期时间函数。我们创建日期并使用 format:mktime()
测试工作日,它返回 1-7 范围内的数字(1 表示星期一)。因此,仅当找到的较高日期不是星期六或星期日时,我们才会更新最大值。strftime()
%u