如何用awk/sed基于另一文件修改稀疏矩阵CSV的指定字段值
适配多Slot修改的AWK解决方案
针对同一用户多条修改记录的场景,这里提供两种可行的AWK脚本方案,完美覆盖需求:
方案一:二维关联数组存储修改记录
BEGIN { FS = OFS = "," } # 先读取slots2change.csv,记录所有需要修改的用户+Slot组合 NR == FNR { changes[$1, $2] = 1 next } # 处理matrix.csv,对匹配的用户修改对应Slot { for (entry in changes) { split(entry, key, SUBSEP) if (key[1] == $1) { # Slot列索引 = Slot号 + 1(首列为User列) col = key[2] + 1 $col = 1 } } print $0 }
原脚本问题分析
你之前的脚本用arr[$1]=$2存储修改记录,同一用户多条记录时,后续的Slot会覆盖之前的,导致只能处理最后一条。本方案用changes[$1, $2]二维关联数组,把每个用户的所有待修改Slot都独立存储,不会丢失任何修改指令。
方案二:按用户分组存储Slot列表(更高效)
如果处理的文件行数较多(比如你的10000行矩阵),这种按用户分组的方式能减少遍历次数,提升效率:
BEGIN { FS = OFS = "," } # 读取修改文件,把同一用户的Slot用空格拼接存入数组 NR == FNR { user_slots[$1] = user_slots[$1] " " $2 next } # 处理矩阵文件,仅遍历当前用户对应的Slot { if ($1 in user_slots) { slot_count = split(user_slots[$1], slot_list, " ") for (i = 1; i <= slot_count; i++) { col = slot_list[i] + 1 $col = 1 } } print $0 }
使用方式
两种方案的调用命令一致:
awk -f modify_slots.awk slots2change.csv matrix.csv
也可以直接把脚本写在命令行里:
awk 'BEGIN {FS=OFS=","} NR==FNR{changes[$1,$2]=1;next} {for(entry in changes){split(entry,key,SUBSEP);if(key[1]==$1){col=key[2]+1;$col=1}} print}' slots2change.csv matrix.csv
内容的提问来源于stack exchange,提问作者ElTitoFranki
相关产品推荐
相关产品推荐

