如何用AWK遍历文件列,保留全列值相同的列并在出现不匹配时终止
实现方案
方案1:基于你原有逻辑的shell循环版本
完全贴合你原本的开发思路,兼容性好,适合中小规模文件使用:
# 替换为你的实际输入文件路径 input_file="input.txt" valid_cols=0 # 读取第一行获取总列数 total_cols=$(awk '{print NF; exit}' "$input_file") for ((i=1; i<=total_cols; i++)); do # 直接统计当前列去重后的行数,不需要临时文件 unique_cnt=$(cut -f"$i" -d " " "$input_file" | sort -u | wc -l) if [ "$unique_cnt" -eq 1 ]; then valid_cols=$i else # 遇到值不一致的列直接终止校验 break fi done # 输出所有校验通过的列,兼容所有列全相同的场景 if [ "$valid_cols" -gt 0 ]; then cut -f1-"$valid_cols" -d " " "$input_file" fi
方案2:高性能awk单命令版本
适合处理大文件,仅需一次文件遍历,无额外IO和子进程开销,性能远高于循环版本:
awk ' BEGIN { FS=" " } # 第一行记录每列的基准值 NR == 1 { for (i=1; i<=NF; i++) base_val[i] = $i max_valid = NF } # 逐行校验列值,遇到不一致的列直接收缩校验范围 { for (i=1; i<=max_valid; i++) { if ($i != base_val[i]) { max_valid = i-1 break } } # 存储所有行的字段供最后输出 for (i=1; i<=max_valid; i++) row[NR][i] = $i } # 统一输出所有有效列 END { if (max_valid < 1) exit for (r=1; r<=NR; r++) { for (c=1; c<=max_valid; c++) { printf "%s%s", row[r][c], c==max_valid ? "\n" : " " } } } ' input.txt
两种方案针对你提供的示例输入,都会输出你要求的前两列结果,完全符合预期。
内容的提问来源于stack exchange,提问作者LP_640
相关产品推荐
相关产品推荐

