如何用awk或sed根据另一文件修改稀疏矩阵指定字段
问题描述
我有一个名为matrix.csv的稀疏矩阵文件,包含10000行、22列,第一列为user,其余列为slot,值为0或1,示例如下:
user1,0,0,0,1,0,0,0,1,0,1,0,0,...,0 user2,0,1,0,0,0,0,0,0,0,0,0,1,...,0 user3,0,0,0,0,0,0,1,0,0,0,1,0,...,0 ...
需要将部分slot的0改为1,另有slots2change.csv文件指定需修改的内容,示例如下:
user1,3 user3,21 ...
即需将user1的第3个slot改为1,user3的第21个slot改为1,预期结果如下:
user1,0,0,1,1,0,0,0,1,0,1,0,0,...,0 user2,0,1,0,0,0,0,0,0,0,0,0,1,...,0 user3,0,0,0,0,0,0,1,0,0,0,1,0,...,1 ...
我尝试了以下命令但未得到正确结果:
awk -F"," 'NR==FNR{user=$1;slot2change=$2} NR!=FNR; /user/ slot2change==0{print $0} ' slots2change.csv matrix.csv
请问如何用awk或sed实现该需求?
解决方案
awk实现(推荐)
核心思路是先把slots2change.csv中的用户-slot映射存入关联数组,再遍历matrix.csv时针对性修改对应字段:
awk -F',' -v OFS=',' ' NR==FNR { # 读取修改规则,存入数组:键为用户名,值为要修改的slot编号 changes[$1] = $2 next } { # 检查当前用户是否有需要修改的slot if ($1 in changes) { # slot编号对应字段号为 slot+1(第一列是user) slot_idx = changes[$1] + 1 $slot_idx = 1 } print $0 }' slots2change.csv matrix.csv
关键逻辑说明:
-F',' -v OFS=',':统一设置输入/输出的分隔符为逗号,确保输出格式与原文件一致。NR==FNR:仅在处理第一个文件(slots2change.csv)时执行,将每个用户对应的修改slot存入数组后跳过后续逻辑。- 处理
matrix.csv时,若当前用户存在于修改规则数组中,计算目标字段的位置(slot编号+1,因为第一列是用户名),将该字段值设为1后输出整行。
sed实现(仅适合小数据量)
sed处理跨文件关联逻辑较为繁琐,需要先生成替换脚本再执行:
- 生成sed替换脚本:
awk -F',' '{ # 构建匹配用户行的正则,以及替换对应slot的表达式 printf "/^%s,/ s/^", $1; for(i=1; i<$2; i++) printf "[^,]*,", $1; printf "[^,]*,0/\\11/\n" }' slots2change.csv > change.sed
- 执行sed命令修改原文件:
sed -f change.sed matrix.csv
这种方法对大数据量(如10000行)效率极低,仅建议在小文件场景下使用。
内容的提问来源于stack exchange,提问作者ElTitoFranki
相关产品推荐
相关产品推荐

