Bash脚本问题:CSV关键词匹配更新列值失败,请求协助
解决CSV关键词匹配并更新状态的Bash脚本问题
需求说明
检查master.csv中是否存在new_param.csv内的关键词,存在则将new_param.csv对应行的第二列设为true,否则设为false。
输入文件内容
new_param.csv
ID Identity as-uid cp_cus_id evs k_n
master.csv
A, xyz, id, abc n, xyz, as-uid, abc, B, xyz, ne, abc q, xyz, id evs, abc 3, xyz, k_n, abc, C, xyz, ad, abc 1, xyz, zd, abc z, xyz, ID, abc
期望输出(更新后的new_param.csv)
ID,true Identity,false as-uid,true cp_cus_id,false evs,true k_n,true
用户错误脚本及报错信息
尝试的Bash脚本
#!/bin/bash declare -a keywords=(`cat new_param.csv`) length=${#keywords[@]} for (( j=0; j<length; j++ )); do a= LC_ALL=C awk -v kw="${keywords[$j]}" -F, '{for (i=1;i<=NF;i++) if ($i ~ kw) {print i}}' master.csv b=0 if [ $a -gt $b ] then echo true $2 >> new_param.csv else echo false $2 >> new_param.csv fi done
报错信息
test.sh: line 29: [: -gt: unary operator expected test.sh: line 33: -f2: command not found
问题分析与修复方案
核心错误点
- 变量赋值语法错误:
a= LC_ALL=C awk ...格式错误,变量赋值时等号不能有空格,且命令结果需用$()或反引号包裹。 - 空值判断逻辑错误:当
awk无输出时$a为空,执行[ $a -gt $b ]会变成[ -gt 0 ],触发运算符错误,需给变量加引号或直接判断输出是否非空。 - 输出逻辑错误:
echo true $2中的$2是脚本位置参数,并非当前循环的关键词,且直接追加到原文件会导致内容混乱。 - 正则匹配隐患:原脚本用
$i ~ kw做正则匹配,关键词中的特殊字符(如-)会干扰匹配结果,改用子串判断更可靠。
修复后的Bash脚本
#!/bin/bash # 创建临时文件存储结果,避免直接修改原文件导致内容混乱 temp_file=$(mktemp) # 逐行读取new_param.csv的关键词 while IFS= read -r keyword; do # 检查master.csv中是否包含当前关键词(子串匹配) if LC_ALL=C awk -v kw="$keyword" -F, '{for(i=1;i<=NF;i++) if(index($i, kw)) exit 0} END{exit 1}' master.csv; then echo "$keyword,true" >> "$temp_file" else echo "$keyword,false" >> "$temp_file" fi done < new_param.csv # 用临时文件替换原文件 mv "$temp_file" new_param.csv
高效单Awk脚本方案(适合大文件)
如果数据量较大,循环调用Awk效率低,可使用单Awk脚本完成所有操作:
#!/bin/bash awk -F, ' # 读取new_param.csv,初始化关键词状态为false NR == FNR { keywords[$1] = "false" next } # 遍历master.csv的每个字段,匹配关键词并更新状态 { for(i=1;i<=NF;i++) { for(kw in keywords) { if(index($i, kw)) { keywords[kw] = "true" } } } } # 输出最终结果 END { for(kw in keywords) { print kw "," keywords[kw] } } ' new_param.csv master.csv > temp.csv && mv temp.csv new_param.csv
内容的提问来源于stack exchange,提问作者ASHOK DAUKIYA
相关产品推荐
相关产品推荐

