使用join和awk合并CSV文件:结果异常及脚本化实现咨询
CSV文件合并解决方案:join去重、awk实现、Bash传参
一、解决join命令重复输出关联键的问题
使用join时默认会把关联键放在结果最开头,而file1的第7列原本就会被输出,导致重复。通过-o参数指定输出列即可避免:
# 输出file1所有列 + file2从第2列开始的所有列 join -t ',' -1 7 -2 1 -o '1.*,2.2-' file1 file2 | head -n 2
-o '1.*'表示输出file1的全部列-o '2.2-'表示输出file2从第2列到最后一列的内容- 这样关联键只会保留file1第7列的一次输出,不会重复
二、用awk实现CSV合并
awk可以更灵活地处理关联逻辑,无需依赖join的排序要求(join需要文件按关联键排序,awk不需要):
awk -F ',' ' # 先读取file2,将第1列作为键,存储其余列内容 NR == FNR { for (i=2; i<=NF; i++) { map[$1] = map[$1] (map[$1] ? "," : "") $i } next } # 处理file1,匹配第7列对应的file2内容并输出 { if ($7 in map) { print $0 "," map[$7] } } ' file2 file1 > file3
逻辑说明:
NR == FNR:仅在处理第一个输入文件(file2)时执行,构建键值对映射- 遍历file1时,判断第7列是否存在于map中,存在则拼接file1行与对应file2内容并输出
三、Bash脚本通过变量传递文件参数
编写可复用的脚本,接收输入文件和输出文件参数:
#!/bin/bash # 检查参数数量是否正确 if [ $# -ne 3 ]; then echo "用法: $0 <输入文件1> <输入文件2> <输出文件>" exit 1 fi # 赋值参数到变量 input1="$1" input2="$2" output="$3" # 选择join或awk实现(注释掉其中一个即可) # 用join实现 join -t ',' -1 7 -2 1 -o '1.*,2.2-' "$input1" "$input2" > "$output" # 用awk实现 # awk -F ',' ' # NR == FNR { # for (i=2; i<=NF; i++) { # map[$1] = map[$1] (map[$1] ? "," : "") $i # } # next # } # { # if ($7 in map) { # print $0 "," map[$7] # } # } # ' "$input2" "$input1" > "$output"
使用方法:
- 保存脚本为
merge_csv.sh,添加执行权限:chmod +x merge_csv.sh - 运行脚本并传入参数:
./merge_csv.sh file1 file2 file3
内容的提问来源于stack exchange,提问作者growler11
相关产品推荐
相关产品推荐

