如何用awk对文件每第5列过滤并简化冗长代码
简化过滤指定列的AWK代码方案
需求:使用awk对文件中第5、10、15……390列(每间隔5列的列)应用过滤条件,要求所有指定列的值均≥10,满足条件时打印整行。如何简化这段冗长的awk代码?
原冗长代码:
awk -F "\t" '{if ($5>=10 && $10>=10 && $15>=10 && $20>=10 && $25>=10 && $30>=10 && $35>=10 && $40>=10 && $45>=10 && $50>=10 && $55>=10 && $60>=10 && $65>=10 && $70>=10 && $75>=10 && $80>=10 && $85>=10 && $90>=10 && $95>=10 && $100>=10 && $105>=10 && $110>=10 && $115>=10 && $120>=10 && $125>=10 && $130>=10 && $135>=10 && $140>=10 && $145>=10 && $150>=10 && $155>=10 && $160>=10 && $165>=10 && $170>=10 && $175>=10 && $180>=10 && $185>=10 && $190>=10 && $195>=10 && $200>=10 && $205>=10 && $210>=10 && $215>=10 && $220>=10 && $225>=10 && $230>=10 && $235>=10 && $240>=10 && $245>=10 && $250>=10 && $255>=10 && $260>=10 && $265>=10 && $270>=10 && $275>=10 && $280>=10 && $285>=10 && $290>=10 && $295>=10 && $300>=10 && $305>=10 && $310>=10 && $315>=10 && $320>=10 && $325>=10 && $330>=10 && $335>=10 && $340>=10 && $345>=10 && $350>=10 && $355>=10 && $360>=10 && $365>=10 && $370>=10 && $375>=10 && $380>=10 && $385>=10 && $390>=10) print}' file
核心简化思路:用循环替代硬编码判断
利用awk的循环特性遍历目标列,无需手动写出所有列的判断条件,代码更简洁且易于维护。
方案1:可读性优先的多行写法
awk -F "\t" '{ pass = 1 for (i = 5; i <= 390; i += 5) { if ($i < 10) { pass = 0 break } } if (pass) print }' file
- 初始化
pass为1,默认当前行符合条件 - 循环变量
i从5开始,每次递增5,覆盖所有目标列 - 一旦发现任意目标列的值小于10,立即标记
pass为0并跳出循环(无需检查剩余列) - 最终若
pass仍为1,打印当前行
方案2:紧凑的单行写法
如果偏好简洁的单行命令,可压缩为:
awk -F "\t" '{p=1;for(i=5;i<=390;i+=5)if($i<10){p=0;break}}p' file
- 利用awk的特性:当条件
p为真时,默认执行print操作,省去显式的if判断
方案3:兼容列数不足的场景
若文件中存在行的列数少于390,可增加列存在性判断避免报错:
awk -F "\t" '{ pass = 1 for (i = 5; i <= 390; i += 5) { if (i > NF || $i < 10) { pass = 0 break } } if (pass) print }' file
- 内置变量
NF表示当前行的总字段数,若i > NF说明该行没有第i列,直接标记为不通过
内容的提问来源于stack exchange,提问作者Ömer A.
相关产品推荐
相关产品推荐

