为sed处理添加循环,解决CSV文件标题截断与邮箱生成问题
解决CSV处理的两个核心问题:保留多值标题+按需生成唯一邮箱
现有场景
现有一段用sed处理file.csv的bash脚本:
#!/bin/bash sed -E 's/([^,]*,([^,]*),) ?(([[:alpha:]])[^ ]* +)(([^,]*),[^,]*,)[^,]*/\1\u\3\u\5\L\4\6\2@example.com/' file.csv > output.csv
待处理的file.csv内容:
id,location_id,name,title,email,directorate 1,1, Amy Lee,Singer,,, 2,2,brad Pitt,Actor,bpitt@example.com,Production 3,5,steven spielberg,Producer,Screenwriter, spielberg@yahoo.com,Production 4,8,Andy lee,Comedian,,Radio
存在的问题
- 标题字段可能包含多值(比如Steven Spielberg的
Producer,Screenwriter),当前脚本会截断逗号后的内容,无法保留完整标题 - 邮箱生成逻辑固定为「名字首字母+姓氏+location_id+@example.com」,不符合需求:仅当邮箱重复时才添加location_id,无重复时直接用「首字母+姓氏@example.com」
解决方案
sed仅适合简单文本替换,处理重复邮箱判断这类需要上下文统计的逻辑,用awk更合适。以下是最终处理脚本:
最终处理脚本
#!/bin/bash awk -F',' -v OFS=',' ' NR == 1 { print $0; next; } { # 格式化name字段:去首尾空格、首字母大写 gsub(/^ +| +$/, "", $3); split($3, name_parts, / +/); first_name = name_parts[1]; last_name = name_parts[2]; formatted_name = toupper(substr(first_name,1,1)) substr(first_name,2) " " toupper(substr(last_name,1,1)) substr(last_name,2); $3 = formatted_name; # 合并多值标题,保留所有内容 title = $4; for (i=5; i<=NF-2; i++) { title = title "," $i; } $4 = title; NF = 4; # 生成邮箱前缀,判断是否需要加location_id email_prefix = tolower(substr(first_name,1,1) last_name); candidate_email = email_prefix "@example.com"; if (email_count[candidate_email]++ > 0) { final_email = email_prefix $2 "@example.com"; } else { final_email = candidate_email; } # 保留原始非空邮箱 original_email = $(NF+1); gsub(/^ +| +$/, "", original_email); if (original_email != "") { final_email = original_email; } # 填充邮箱和部门字段,输出结果 $5 = final_email; $6 = $(NF+2); gsub(/^ +| +$/, "", $6); print $0; } ' file.csv > output.csv
处理后输出结果
id,location_id,name,title,email,directorate 1,1,Amy Lee,Singer,alee@example.com,, 2,2,Brad Pitt,Actor,bpitt@example.com,Production 3,5,Steven Spielberg,Producer,Screenwriter,sspielberg@example.com,Production 4,8,Andy Lee,Comedian,alee8@example.com,Radio
关键逻辑说明
- 保留完整标题:遍历从第4字段到倒数第2字段,合并所有标题值,彻底解决多值标题被截断的问题
- 按需生成唯一邮箱:用数组记录邮箱出现次数,首次出现用无location_id的邮箱,重复则自动追加location_id;同时保留原始已存在的邮箱,不覆盖有效数据
- 自动格式化名字:去除首尾空格,将名字首字母统一大写
内容的提问来源于stack exchange,提问作者Art
相关产品推荐
相关产品推荐

