如何在Unix中过滤唯一行并合并指定列数据?
CSV用户权限合并与最新登录日期保留方案
需求示例
原始输入CSV
User,Rights,Login_date A,Admin,12-SEP-23 A,Accountant,01-SEP-23 B,Admin,05-SEP-23 B,Clerk,31-AUG-23
期望输出CSV
User,Rights,Login_date A,Admin|Accountant,12-SEP-23 B,Admin|Clerk,05-SEP-23
解决方案
方案1:Python Pandas实现
适合需要灵活数据处理的场景,步骤如下:
- 确保已安装Pandas:
pip install pandas - 编写处理脚本:
import pandas as pd # 读取输入CSV df = pd.read_csv("input.csv") # 转换日期格式为可排序的datetime类型 df["Login_date"] = pd.to_datetime(df["Login_date"], format="%d-%b-%y") # 按用户分组,合并权限列,保留最新登录日期 processed_df = df.groupby("User").agg( Rights=("Rights", "|".join), Login_date=("Login_date", "max") ).reset_index() # 将日期转回原始格式(大写月份缩写) processed_df["Login_date"] = processed_df["Login_date"].dt.strftime("%d-%b-%y").str.upper() # 保存结果到输出CSV processed_df.to_csv("output.csv", index=False)
方案2:Shell AWK命令实现
适合无Python环境的服务器场景,无需额外安装依赖:
- 创建AWK脚本文件
merge_rights.awk:
BEGIN { FS = "," OFS = "," print "User,Rights,Login_date" } NR > 1 { # 将日期转换为可比较的数字格式(YYYYMMDD) split($3, date_parts, "-") # 映射月份缩写到数字 month_map["JAN"]=1; month_map["FEB"]=2; month_map["MAR"]=3; month_map["APR"]=4 month_map["MAY"]=5; month_map["JUN"]=6; month_map["JUL"]=7; month_map["AUG"]=8 month_map["SEP"]=9; month_map["OCT"]=10; month_map["NOV"]=11; month_map["DEC"]=12 date_num = 20 substr(date_parts[3],1,2) * 10000 + month_map[date_parts[2]] * 100 + date_parts[1] # 聚合用户权限与最新日期 if (!($1 in user_rights)) { user_rights[$1] = $2 user_latest_date[$1] = date_num user_latest_date_str[$1] = $3 } else { user_rights[$1] = user_rights[$1] "|" $2 if (date_num > user_latest_date[$1]) { user_latest_date[$1] = date_num user_latest_date_str[$1] = $3 } } } END { # 输出处理结果 for (user in user_rights) { print user, user_rights[user], user_latest_date_str[user] } }
- 执行命令处理CSV:
awk -f merge_rights.awk input.csv > output.csv
内容的提问来源于stack exchange,提问作者Joli Gogoi
相关产品推荐
相关产品推荐

