【问题标题】:Sorting csv file based on column 2 only. if 2 rows of column 2 are same, should be input file order only. should not sort based on any other column仅基于第 2 列对 csv 文件进行排序。如果第 2 列的 2 行相同,则应仅输入文件顺序。不应基于任何其他列进行排序
【发布时间】:2020-03-21 07:07:42
【问题描述】:

我看过很多关于根据列对文件进行排序的帖子,但对我没有帮助。

我只想根据第 2 列对 CSV 文件进行排序。

例如:我文件中的数据如下所示

H1,H2,H3,H4
C11,R_G,S_F_G,22-OCT-2019
C12,R_G,S_F_G,22-OCT-2019
C13,R_E,S_F_E,22-OCT-2019
C13,R_E,S_F_E_RA,22-OCT-2019
C13,R_E,S_F_E_RB,22-OCT-2019
C14,R_E,S_F_E,22-OCT-2019
C14,R_E,S_F_E_RA,22-OCT-2019
C14,R_E,S_F_E_RB,22-OCT-2019

第 2 列的预期排序顺序如下所示

H1,H2,H3,H4
C13,R_E,S_F_E,22-OCT-2019
C13,R_E,S_F_E_RA,22-OCT-2019
C13,R_E,S_F_E_RB,22-OCT-2019
C14,R_E,S_F_E,22-OCT-2019
C14,R_E,S_F_E_RA,22-OCT-2019
C14,R_E,S_F_E_RB,22-OCT-2019
C11,R_G,S_F_G,22-OCT-2019
C12,R_G,S_F_G,22-OCT-2019

我尝试使用以下命令进行排序

awk 'NR==1; NR > 1 {print $0 | "sort -t, -k2"}' inputfile >> outputfile

结果如下

H1,H2,H3,H4
C13,R_E,S_F_E,22-OCT-2019
C14,R_E,S_F_E,22-OCT-2019
C13,R_E,S_F_E_RA,22-OCT-2019
C14,R_E,S_F_E_RA,22-OCT-2019
C13,R_E,S_F_E_RB,22-OCT-2019
C14,R_E,S_F_E_RB,22-OCT-2019
C11,R_G,S_F_G,22-OCT-2019
C12,R_G,S_F_G,22-OCT-2019

如果您观察结果,第 2 列和第 3 列正在排序,但我只希望对第 2 列进行排序,如果第 2 列与 2 行相同,则它应该按照输入文件中出现的顺序排列。

如果有人能帮助我理解我做错了什么,那就太好了

【问题讨论】:

  • glen Jackman 的回答太棒了unix.stackexchange.com/q/345076/273492
  • ts 不重复 @RaviSaroch 我希望仅根据第 2 列进行排序。如果第 2 列中的 2 行相同,则应按输入文件中的出现顺序排列。我已经尝试过您提到的解决方案。感谢您的宝贵时间。
  • @Raj 你见过这个答案stackoverflow.com/a/59041272/757714 吗?不好吗?为什么?谢谢
  • @aborruso 由于管理员限制,我将无法安装。即使我在获得批准后安装在我的开发机器中,将其安装在我的生产服务器中也是一项艰巨的工作,因为其中涉及很多批准过程。

标签: shell csv unix awk


【解决方案1】:

为什么不简单地使用headtailsort,例如

head -n1 file; tail -n+2 file | sort -t, -k2

head -n1 file 的使用只是简单地输出标题,然后使用tail -n+2 file 获得的剩余行通过管道传送到sort -t, -k2 进行排序,结果是带有标题的完整排序文件。

要创建包含排序结果的新文件,请在子 shell 中运行命令行并将输出重定向到新文件,例如

(head -n1 file; tail -n+2 file | sort -t, -k2) > sortedfile

(如果你愿意,你可以使用rm file; mv sortedfile file的2步将原始文件替换为排序文件)

使用/输出示例

$ head -n1 file; tail -n+2 file | sort -t, -k2
H1,H2,H3,H4
C13,R_E,S_F_E,22-OCT-2019
C14,R_E,S_F_E,22-OCT-2019
C13,R_E,S_F_E_RA,22-OCT-2019
C14,R_E,S_F_E_RA,22-OCT-2019
C13,R_E,S_F_E_RB,22-OCT-2019
C14,R_E,S_F_E_RB,22-OCT-2019
C11,R_G,S_F_G,22-OCT-2019
C12,R_G,S_F_G,22-OCT-2019

【讨论】:

  • 感谢您抽出宝贵时间@David Rankin。我希望仅根据第 2 列进行排序。如果第 2 列中的 2 行相同,则它应该按照输入文件中出现的顺序排列。如果您观察您发布的结果,当第 2 列相同时,它会根据第 1/3 列进行排序。但我希望它与输入文件的顺序相同。请注意我在问题中提到的预期结果。
  • 我明白你在说什么。这可能需要手动排序,因为即使使用 awk sort 或带有 shell 的 sort,对所使用的算法也几乎没有控制。您几乎需要冒泡或插入排序。我会在一两个小时后有时间进一步研究它。
【解决方案2】:

使用 Miller (https://github.com/johnkerl/miller) 并运行

mlr --csv sort -f H2 input.csv

你会有

H1,H2,H3,H4
C13,R_E,S_F_E,22-OCT-2019
C13,R_E,S_F_E_RA,22-OCT-2019
C13,R_E,S_F_E_RB,22-OCT-2019
C14,R_E,S_F_E,22-OCT-2019
C14,R_E,S_F_E_RA,22-OCT-2019
C14,R_E,S_F_E_RB,22-OCT-2019
C11,R_G,S_F_G,22-OCT-2019
C12,R_G,S_F_G,22-OCT-2019

【讨论】:

  • “mlr”无法识别。看起来我必须安装/配置米勒项目。如果是,我需要经过很多审批流程@aborruso。能否请您告诉我 id 可以使用 awk/其他一些常规命令来实现。感谢您的宝贵时间。
  • @Raj Miller 是 awk、sed、cut、join 和排序的名称索引数据,例如 CSV、TSV 和表格 JSON。安装很简单johnkerl.org/miller/doc/build.html#Prebuilt_executables
【解决方案3】:

试试这个:-

sort --field-separator=',' --key=2 filename

--field-separator=',' => 字段分隔符是","

--key=2 或 -k 2 :根据第二列编号对数据进行排序

【讨论】:

  • 感谢您抽出宝贵时间@RaviSaroch。我希望仅根据第 2 列进行排序。如果第 2 列中的 2 行相同,则应按输入文件中出现的顺序排列。我已经尝试过您提到的解决方案。如果您观察您发布的结果,当第 2 列相同时,它会根据第 1/3 列进行排序。但我希望它与输入文件的顺序相同。请注意我在问题中提到的预期结果
猜你喜欢
  • 2022-11-16
  • 1970-01-01
  • 2018-11-23
  • 2012-02-18
  • 2013-06-26
  • 2014-06-07
  • 2021-11-08
  • 2011-10-23
  • 2012-04-08
相关资源
最近更新 更多