You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于CSV第5列值重排行?现有Shell方案需优化

问题:根据CSV第5列键值重排行数据,将目标行移至顶部

需求说明

  • 处理CSV文件test.csv,把第1列值等于第5列唯一键值的行移到所有数据行最前面
  • 保留原表头,其余数据行维持原有顺序

测试文件内容 (test.csv)

Col A,Col B,Col C,Col D,Col E
A,Data 1,Category 1,Name 1,C
B,Data 2,Category 2,Name 2,C
C,Data 3,Category 3,Name 3,C
D,Data 4,Category 4,Name 4,C
E,Data 5,Category 5,Name 5,C
F,Data 6,Category 6,Name 6,C

期望输出

Col A,Col B,Col C,Col D,Col E
C,Data 3,Category 3,Name 3,C
A,Data 1,Category 1,Name 1,C
B,Data 2,Category 2,Name 2,C
D,Data 4,Category 4,Name 4,C
E,Data 5,Category 5,Name 5,C
F,Data 6,Category 6,Name 6,C

原实现代码(生成多个临时文件)

sed 1d test.csv > input.csv 
key=`awk -F"," -v 'OFS=,' '{ print $5}' input.csv | uniq`
awk -F"," -v 'OFS=,' '{if($1 == "'$key'") print}' input.csv > temp.csv
cat temp.csv input.csv > temp2.csv

awk '!seen[$0]++' temp2.csv > output.csv

sed -i '1iCol A,Col B,Col C,Col D,Col E' output.csv

优化方案(无临时文件,单Awk命令搞定)

用Awk一次性完成所有逻辑,不需要生成任何临时文件,代码如下:

awk -F',' -v OFS=',' '
    NR == 1 { print; next }
    NR == 2 { key = $5 }
    $1 == key { target = $0; next }
    { lines[++n] = $0 }
    END { print target; for (i=1; i<=n; i++) print lines[i] }
' test.csv > output.csv

代码逻辑解释

  • 第一行是表头,直接输出后跳过后续处理
  • 从第二行(第一行数据)提取第5列的键值(默认所有数据行第5列值一致)
  • 匹配到第1列等于键值的行,单独存到变量里,不加入普通行数组
  • 所有非目标行存入数组,记录行数
  • 最后先输出目标行,再依次输出数组里的其余行

如果需要直接覆盖原文件(注意提前备份),可以用sponge命令(需安装moreutils包):

awk -F',' -v OFS=',' '
    NR == 1 { print; next }
    NR == 2 { key = $5 }
    $1 == key { target = $0; next }
    { lines[++n] = $0 }
    END { print target; for (i=1; i<=n; i++) print lines[i] }
' test.csv | sponge test.csv

内容的提问来源于stack exchange,提问作者zxcv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 07:40:36