AWK脚本对比CSV文件无输出,求修正(含需求与脚本)
AWK脚本排查:CSV日期匹配筛选无输出问题
需求
作为AWK新手,需完成以下操作:
- 对比两个CSV文件:FILE1.csv(漏洞扫描数据)和FILE2.csv(主机扫描日期)
- 从FILE2中提取每个主机的三类扫描日期(Agent扫描、非凭证扫描、凭证扫描)
- 按规则选择目标日期:优先比较Agent和凭证扫描日期,取最新的;若其中一个为空则取非空的;若都为空则用非凭证扫描日期
- 筛选FILE1中
Last Observed列与目标日期匹配的条目
当前脚本无输出,需排查修复。
文件内容
FILE1.csv
Name,Plugin,Plugin Name,First Discovered,Last Observed,Severity server1.domain,57608,SMB Signing not required,9/19/2020 20:55,12/3/2022 20:39,Medium server1.domain,71966,Oracle Java SE Multiple Vulnerabilities (January 2014 CPU),4/22/2021 3:08,12/1/2022 3:14,Critical server1.domain,94138,Oracle Java SE Multiple Vulnerabilities (October 2016 CPU),4/22/2021 3:08,12/8/2022 3:14,Critical server2.domain,156032,Apache Log4j Unsupported Version Detection,12/25/2021 3:07,12/8/2022 3:07,Critical server2.domain,156032,Apache Log4j Unsupported Version Detection,8/31/2022 11:48,11/30/2022 10:16,Critical server2.domain,156103,Apache Log4j 1.2 JMSAppender Remote Code Execution (CVE-2021-4104),12/25/2021 3:07,12/6/2022 3:07,High server3.domain,164078,Splunk Enterprise and Universal Forwarder < 9.0 Improper Certificate Validation,10/31/2022 3:13,11/30/2022 10:16,High server3.domain,166960,Tenable Nessus Agent 10.x < 10.2.1 Multiple Vulnerabilities (TNS-2022-22),11/7/2022 3:14,12/3/2022 3:14,High server3.domain,168362,VMware Tools 10.x / 11.x / 12.x < 12.1.5 DoS (VMSA-2022-0029),12/5/2022 3:14,12/8/2022 3:14,Low
FILE2.csv
Name,LAST_VULN_AGENT_SCAN,LAST_VULN_NONCRED_SCAN,LAST_VULN_CRED_SCAN server1.domain,12/8/2022 3:14,12/3/2022 20:39, server2.domain,,12/8/2022 3:07, server3.domain,,12/3/2022 3:14,12/8/2022 3:14
期望输出
Name,Plugin,Plugin Name,First Discovered,Last Observed,Severity server1.domain,94138,Oracle Java SE Multiple Vulnerabilities (October 2016 CPU),4/22/2021 3:08,12/8/2022 3:14,Critical server2.domain,156032,Apache Log4j Unsupported Version Detection,12/25/2021 3:07,12/8/2022 3:07,Critical server3.domain,168362,VMware Tools 10.x / 11.x / 12.x < 12.1.5 DoS (VMSA-2022-0029),12/5/2022 3:14,12/8/2022 3:14,Low
当前脚本
awk -F',' 'NR==FNR{a[$2,$3,$4];next} if (a[$2] && a[$4]) { if(a[$2] > a[$4]) { if ($5 == a[$2]) print $0; } else { if ($5 == a[$4]) print $0; } } else if (a[$2]) { if ($5 == a[$2]) print $0; } else if (a[$4]) { if ($5 == a[$4]) print $0; } else { if ($5 == a[$3]) print $0; }' FILE1.csv FILE2.csv
逻辑说明
if [ ! -z ${LAST_VULN_AGENT_SCAN} ] && [ ! -z ${LAST_VULN_CRED_SCAN} ]; then # Agent扫描和凭证扫描日期均非空 if [ "${AGENT_EPOCH}" -gt "${CRED_EPOCH}" ]; then # Agent扫描日期更新,用该日期筛选FILE1的Last Observed列 else # 凭证扫描日期更新,用该日期筛选 fi elif [ ! -z ${LAST_VULN_AGENT_SCAN} ] && [ -z ${LAST_VULN_CRED_SCAN} ]; then # 仅Agent扫描日期非空,用该日期筛选 elif [ -z ${LAST_VULN_AGENT_SCAN} ] && [ ! -z ${LAST_VULN_CRED_SCAN} ]; then # 仅凭证扫描日期非空,用该日期筛选 else # 前两类日期均为空,用非凭证扫描日期筛选 fi
问题排查与修正
当前脚本核心错误
- 文件顺序错误:
NR==FNR处理第一个输入文件,脚本中先传了FILE1.csv,但应该先处理FILE2.csv(需要先存储主机的日期信息) - 数组存储逻辑错误:当前用
a[$2,$3,$4]存储,没有关联主机名,无法通过主机匹配日期;且仅存了键,没有存储日期值 - 日期比较错误:直接用字符串比较日期(如
a[$2] > a[$4])不准确,需转换为epoch时间戳再比较 - AWK语法错误:代码块未用大括号包裹,
&&是HTML转义字符,实际应使用&&
修正后的脚本
#!/usr/bin/awk -f # 转换日期为epoch时间戳 function date_to_epoch(date_str) { cmd = "date -d \"" date_str "\" +%s 2>/dev/null" cmd | getline epoch close(cmd) return epoch } BEGIN { FS = "," OFS = "," } # 处理FILE2.csv,存储每个主机的三类扫描日期 NR == FNR { if (NR == 1) next # 跳过表头 host = $1 agent_date = $2 noncred_date = $3 cred_date = $4 # 按规则选择目标日期 target_date = noncred_date # 默认用非凭证扫描日期 if (agent_date != "" && cred_date != "") { # 比较Agent和凭证扫描的epoch时间,取更新的 agent_epoch = date_to_epoch(agent_date) cred_epoch = date_to_epoch(cred_date) target_date = (agent_epoch > cred_epoch) ? agent_date : cred_date } else if (agent_date != "") { target_date = agent_date } else if (cred_date != "") { target_date = cred_date } host_target_date[host] = target_date next } # 处理FILE1.csv,筛选匹配目标日期的条目 { if (NR == 1) { print; next } # 输出表头 host = $1 last_observed = $5 if (last_observed == host_target_date[host]) { print $0 } }
使用方式
执行时需调整文件顺序,先传FILE2.csv:
awk -f fix_script.awk FILE2.csv FILE1.csv
说明
date_to_epoch函数将日期字符串转换为epoch时间,确保日期比较的准确性(需系统支持date -d,如GNU date)- 先处理FILE2.csv,为每个主机存储最终要匹配的目标日期
- 处理FILE1.csv时,直接对比
Last Observed列与主机的目标日期,匹配则输出条目
内容的提问来源于stack exchange,提问作者27560
相关产品推荐
相关产品推荐

