如何高效筛选CSV:按第一列子串分组,每组仅保留前3条记录?
使用AWK高效实现按重复子串分组保留前3条记录
针对你的需求,AWK是更高效的解决方案——它只需单趟扫描文件,无需预先提取唯一子串再循环执行grep,避免了多次读取文件的开销,尤其适合处理大体积CSV文件。
核心实现思路
- 以CSV的逗号作为分隔符(可根据实际分隔符调整);
- 从第一列中提取用于分组的重复子串作为
key; - 维护一个计数器哈希表,记录每个
key已输出的行数; - 仅当计数器小于3时输出当前行,并递增计数器。
示例代码
以下针对你给出的索引格式,提供三种常见分组规则的实现:
规则1:按后缀(如_apex/_LA)分组
如果重复子串是第一列末尾的apex或LA部分:
BEGIN { FS = "," } { # 提取"-1-H0025_"之后的子串作为分组key key_start = index($1, "-1-H0025_") + length("-1-H0025_") key = substr($1, key_start) if (count[key] < 3) { print $0 count[key]++ } }
规则2:按前缀(如AAACCC/TTTG)分组
如果重复子串是第一列的前缀部分(比如前6个字符):
BEGIN { FS = "," } { # 提取前6个字符作为分组key key = substr($1, 1, 6) if (count[key] < 3) { print $0 count[key]++ } }
规则3:按-分隔的第三部分分组
如果重复子串是-分割后的第三段(如H0025_apex/H0025_LA):
BEGIN { FS = "," } { split($1, parts, "-") key = parts[3] if (count[key] < 3) { print $0 count[key]++ } }
使用方式
将上述代码保存为filter.awk,然后执行:
awk -f filter.awk your_file.csv
或者直接在命令行执行(以规则1为例):
awk 'BEGIN {FS=","} {key_start=index($1,"-1-H0025_")+11; key=substr($1,key_start); if(count[key]<3){print $0; count[key]++}}' your_file.csv
对比原方案的优势
- 效率更高:仅需一次读取文件,避免了循环
grep时多次I/O操作的开销; - 内存占用低:仅维护一个小型哈希表记录计数器,无需存储所有唯一子串;
- 灵活性强:可通过修改
key的提取逻辑适配任意子串分组规则。
内容的提问来源于stack exchange,提问作者pino
相关产品推荐
相关产品推荐

