如果第 2 列存在,则删除重复行

如果第 2 列存在,则删除重复行

我正在处理超过 10k 行的示例数据,类似于以下内容:

hxxp://google.com 
hxxp://google.com "Seen"
hxxp://yahoo.com "Check again"
hxxp://yahoo.com 
hxxp://about.com
hxxp://x.com
hxxp://y.com
hxxp://z.com
hxxp://reddit.com
hxxp://a.com "good"
hxxp://a.com
hxxp://b.com "good"
hxxp://c.com
hxxp://c.com "good"
hxxp://c.com

我一直在努力寻找一种方法来实现这些结果:

hxxp://google.com "Seen"
hxxp://yahoo.com "Check again"
hxxp://about.com
hxxp://x.com
hxxp://y.com
hxxp://z.com
hxxp://reddit.com
hxxp://a.com "good"
hxxp://b.com "good"
hxxp://c.com "good"

在示例数据中,可能存在重复行。如果存在重复行,请删除缺少第二列的行。分隔符是空格。

awk -F' ' '!seen[$1]++' dupe.txt > clean.txt

这似乎不是适合我的衬里。

答案1

$ LC_ALL=C sort -r <file | LC_ALL=C sort -k1,1 -us
hxxp://a.com "good"
hxxp://about.com
hxxp://b.com "good"
hxxp://c.com "good"
hxxp://google.com "Seen"
hxxp://reddit.com
hxxp://x.com
hxxp://y.com
hxxp://yahoo.com "Check again"
hxxp://z.com

第一个sort以相反的顺序对文件进行排序,使用整行作为排序键。这将产生中间结果

hxxp://z.com
hxxp://yahoo.com "Check again"
hxxp://yahoo.com
hxxp://y.com
hxxp://x.com
hxxp://reddit.com
hxxp://google.com "Seen"
hxxp://google.com
hxxp://c.com "good"
hxxp://c.com
hxxp://c.com
hxxp://b.com "good"
hxxp://about.com
hxxp://a.com "good"
hxxp://a.com

给定示例数据。请注意,包含额外注释的行始终位于不带额外注释的相应行之前。

第二个sort仅生成排序键唯一的行。我们仅使用第一个字段(URL)作为排序键。我们还要求sort使用“稳定”的排序算法-s。这意味着具有相同键的行的顺序不会改变输入中的顺序。

-u和组合-s仅提供带有重复 URL 的额外注释的行。

这个LC_ALL=C位是为了确保sort获得一个合理的区域设置,以便行正确排序以使其正常工作。

答案2

如果您的示例包含您的所有状态并假设您的文件名为 Sample.data:

grep " " Sample.data > Result
cut -d' ' -f1 Result > FirstCol
grep Sample.data -v -f FirstCol >> Result

答案3

你可以这样做:

awk '
    !($1 in a) || NF > 1 {a[$1] = $0} 
    END {for (url in a) print a[url]}
' dupe.txt

行的顺序将不会被保留。

这将保持顺序,但需要对文件进行 2 次传递:

awk '
    NR == FNR {
        if (!($1 in a) || NF > 1) {a[$1] = $0} 
        next
    }
    $0 == a[$1]
' dupe.txt dupe.txt

答案4

perl -lane '
    push @h, $F[0] if ! exists $h{$F[0]};
    $h{$F[0]} = $_ if ! exists $h{$F[0]} || @F > 1;
    }{ print $h{$_} for @h;
' dupe.txt > clean.txt

解释:

  • @h存储键(即第一个字段)出现的顺序。
  • %h是第一个字段上的哈希值,$F[0]相应的值是 toto 中的行。
  • %h每当看到一个新密钥时,或者当我们看到一个旧密钥但该行有多个字段时,哈希值都会更新,在这种情况下,更新的时机就成熟了。
  • 在 处eof,我们只需循环存储在数组中的键@h并提取相应的值并将其发送到标准输出。

输出:

xxp://google.com "Seen"
hxxp://yahoo.com "Check again"
hxxp://about.com
hxxp://x.com
hxxp://y.com
hxxp://z.com
hxxp://reddit.com
hxxp://a.com "good"
hxxp://b.com "good"
hxxp://c.com "good"

相关内容