【问题标题】:How to delete partial duplicate lines with AWK?如何使用 AWK 删除部分重复行?
【发布时间】:2010-12-08 01:36:03
【问题描述】:

我有这些重复行的文件,其中只有最后一个字段不同:

OST,0202000070,01-AUG-09,002735,6,0,0202000068,4520688,-1,0,0,0,0,0,55
ONE,0208076826,01-AUG-09,002332,316,3481.055935,0204330827,29150,200,0,0,0,0,0,5
ONE,0208076826,01-AUG-09,002332,316,3481.055935,0204330827,29150,200,0,0,0,0,0,55
OST,0202000068,01-AUG-09,003019,6,0,0202000071,4520690,-1,0,0,0,0,0,55

我需要删除第一个出现的行并保留第二个。

我试过了:

awk '!x[$0]++ {getline; print $0}' file.csv

但它没有按预期工作,因为它还删除了不重复的行。

【问题讨论】:

  • 您的(近)重复项总是相邻还是可以穿插?
  • 它们总是相邻的,因为它们已经是另一个 awk 操作的结果。

标签: unix awk duplicate-data lines


【解决方案1】:

作为一般策略(尽管我和 Aho 一起上课,但我不是 AWK 专业人士)您可以尝试:

  1. 连接所有字段,除了 最后一个。
  2. 将此字符串用作哈希的键。
  3. 将整行存储为值 散列。
  4. 处理完所有行后, 循环打印出散列 值。

这不是 AWK 特定的,我不能轻易提供任何示例代码,但这是我首先尝试的。

【讨论】:

    【解决方案2】:
    #!/bin/awk -f
    {
        s = substr($0, 0, match($0, /,[^,]+$/))
        if (!seen[s]) {
            print $0
            seen[s] = 1
        }
    }
    

    【讨论】:

    • 这个需要在右方括号后加一个星号来匹配正确的子字符串。除此之外,它与awk '!x[substr($0, 1,16)]++ ' file.csv 相同。它们都受苦于打印一组近似副本中的第一个,而不是最后一个。
    • 与此训练数据相同,即
    • 感谢您的更正,并很好地了解了 OP 的要求
    • 您可以通过将其夹在tac 的调用之间来“正确地”工作,例如tac | script.awk file.txt | tac。当然,如果你有幸拥有 tac。 :)
    • 我的意思是tac | script.awk | tac file.txt
    【解决方案3】:

    如果您的近重复项总是相邻的,您可以只与上一个条目进行比较,避免创建潜在的巨大关联数组。

    #!/bin/awk -f
    {
        s = substr($0, 0, match($0, /,[^,]*$/))
        if (s != prev) {
            print prev0
        }
        prev = s
        prev0 = $0
    } 
    END {
        print $0
    }
    

    编辑:更改了脚本,使其打印一组几乎重复的最后一个(不需要tac)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-06
      • 2017-07-09
      • 1970-01-01
      • 2015-08-24
      • 1970-01-01
      • 1970-01-01
      • 2015-05-28
      相关资源
      最近更新 更多