【问题标题】:Output the smallest valued duplicate in a csv file在 csv 文件中输出最小值的重复项
【发布时间】:2013-02-22 07:43:49
【问题描述】:

我有一个 CSV 文件,其中包含大量价格不同的重复项目,并且该文件已排序。 我想比较所有重复的项目并查看哪个重复项目的价格最低,然后将价格最低的重复项目导出到新文件 字段用逗号分隔 所以原始 CSV 文件:

01,香蕉,7.00
01,香蕉,6.00
01,香蕉,7.00
01,香蕉,9.00
02,芒果,5.00
02,芒果,3.00
02,芒果,3.00
02,芒果,4.00

输出 CSV 文件应该是

01,香蕉,6.00
02,芒果,3.00

我目前在 bash 中编码,想知道 awk 是否可以做到这一点。

【问题讨论】:

  • 使用awk的琐碎,你试过什么?
  • 好吧,我一直在搜索并尝试过这个:awk '!x[$1,$2]++' FS=":" file.txt
  • 但这会比较两列并检查它们是否相同,但显然这不是我的目的,我只是想找出哪个重复项更小
  • 这只是计算重复,而不是比较价格。而FS=":" 表示各列之间用: 分隔,而不是空格。
  • 所以编写一个脚本,将$3保存在关联数组中,并比较新的和保存的是否更小。

标签: bash csv awk duplicates


【解决方案1】:
awk '!($1" "$2 in x) || x[$1" "$2] > $3 {x[$1" "$2] = $3}
     END {for (item in x) print item, x[item]}' file.txt
  • $1" "$2 == 前两列用空格连接
  • !(... in x) == is ... not found as a key in the array x?
  • x[...] > $3 == 是 x 的 ... 元素大于第 3 列

所以如果x中没有找到商品编号+名称,或者保存的价格大于当前行,我们执行大括号中的代码:

  • {x[...] = $3} == 将价格保存为 x 的 ... 元素

END,我们循环遍历x 中的所有项目,并打印项目和保存的价格。

【讨论】:

  • 你能解释一下每个部分的含义吗?我想了解这段代码,而不仅仅是复制和粘贴
  • 哦,我忘了说这是一个csv文件
  • 它适用于您在问题中显示的文件,该文件以空格分隔。
  • 使用-F 选项到awk 指定字段分隔符(如果它不是空格)。
【解决方案2】:

由于文件已排序(按键分组),您可以尝试这样做以节省一些内存并保持顺序:

awk '
  p!=$1 OFS $2 {
    if(p)print p,v
    p=$1 OFS $2
    v=$3
    next 
  } 
  $3<v {
    v=$3
  } 
  END{
    print p,v
  }
' FS=, OFS=, file

或者如果 $1 是唯一键,你也可以试试这个:

awk '
  p x!=$1 {
    if(p x)print s
    p=$1
    s=$0
    v=$3
    next 
  } 
  $3<v {
    v=$3
  } 
  END{
    print s
  }
' FS=, file 

注意:如果是带有引号字段的 csv 文件,那么脚本需要变得更复杂。

【讨论】:

    猜你喜欢
    • 2020-02-04
    • 1970-01-01
    • 2018-08-12
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多