查找在 2 列文件中出现次数最少的值

问题描述 投票:0回答:3

我有一个这种结构的动态生成的 txt 文件 -> Code[space]Link

这很简单

15210 https://test1.com
4 https://test2.com
1020 https://testc.com
152 https://testz.com
152 https://test5.com
10 https://test54.com
152 https://testx.com
10 https://testds.com
15210 https://testmp.com

可以变大到亿行

我只想显示文件上的所有链接,例如,仅当相同的代码没有重复超过或等于 3 次时。

在这种情况下输出将是

https://test1.com
https://test2.com
https://testc.com
https://test54.com
https://testds.com
https://testmp.com

152 代码前面的所有链接都不会在输出中显示,因为 152 重复了 >= 3 次。如果任何其他代码值重复 >=3 次,则相同。

只是,我希望在上面的例子中这个条件的数量是 3 是用户在命令中输入的。

shell text-processing
3个回答
3
投票

你可以像这样做一个两遍解决方案:

awk 'FNR==NR{cnt[$1]++; next} cnt[$1]<3{print $2}' file file 

印花:

https://test1.com
https://test2.com
https://testc.com
https://test54.com
https://testds.com
https://testmp.com

或者,如果您在

$1
中定义了一些元素,而您无法将它们保存在内存中,您可以先排序,然后将块分开,然后只在块中的行中打印
$2
少于3行:

sort -n file | awk '
    $1==last || FNR==1{print; last=$1; next}
    {last=$1; print ""; print}
' | awk '
    BEGIN { RS = "" ; FS = "\n" }
    NF<3{for(i=1;i<=NF;i++) {
        split($i, a, " ")
        print a[2]
        }
    }
'

这样会比较慢,原文件中的顺序会丢失


2
投票

您也可以使用

awk
一次性完成排序输出。例如你可以这样做:

sort -n yourfile |
awk '
  FNR == 1 {
    code = $1
    lasturl[$2] = 1
    n = 1
    next
  }
  $1 == code {
    n++
    lasturl[$2] = 1
    next
  } 
  {
    if (n < 3) {
      for (i in lasturl)
        print i
    }
    code = $1
    delete lasturl
    lasturl[$2] = 1
    n = 1
  }
  END { if (n < 3) for (i in lasturl) print i }
'

(最大数组只是重复代码的最大数量(例如,三个

152
代码的 3 个元素)而不是每个代码的一个元素)

示例使用/输出

sort -n
会改变你的输出顺序,但是在上面的
yourfile
中输入你会得到:

https://test2.com
https://testds.com
https://test54.com
https://testc.com
https://testmp.com
https://test1.com

如果您有任何问题,请告诉我。


0
投票

使用任何 awk 和排序:

$ cat tst.sh
#!/usr/bin/env bash

sort -k1,1 "${@:--}" |
awk -v max=3 '
    $1 != prev {
        if ( cnt < max  ) {
            printf "%s", codes
        }
        prev  = $1
        cnt   = 0
        codes = ""
    }
    {
        cnt++
        codes = codes $2 ORS
    }
    END {
        if ( cnt < max ) {
            printf "%s", codes
        }
    }
'

$ ./tst.sh file
https://test54.com
https://testds.com
https://testc.com
https://test1.com
https://testmp.com
https://test2.com
© www.soinside.com 2019 - 2024. All rights reserved.