【问题标题】:Get count of records in file with a filter in file使用文件中的过滤器获取文件中的记录数
【发布时间】:2019-07-06 23:03:14
【问题描述】:

我有一个文件 |分隔,文件有 4 列

123|456|789|234
456|456|789|2345
124|456|789|2345
125|456|789|2345
126|456|789|2345
128|451|782|2345

输出 --> 6

如何在 col2=456 和 col3=789 的 column1 中找到不同记录的计数。

我知道如何找到整个文件的 col1 的不同,但是在对其他列应用一些过滤器后我们如何找到

【问题讨论】:

  • 要不要输出5,最后一行要跳过?

标签: unix awk sed scripting cut


【解决方案1】:

请您尝试关注一下。

awk -F'|' '$2==456 && $3==789 && !a[$1,$2,$3]++{count++} END{print count}' Input_file

【讨论】:

  • @Vijiy,确保创建一个索引为 $1、$2 和 $3 和 !a[...]]++ 的数组意味着条件仅在这 3 个项目第一次出现时为 TRUE数组,一旦条件为真,则变量 count 的值将递增 1,并在 END 部分的末尾打印 count 的值。
  • @Vijiy,我也会在几分钟后在我的帖子中添加完整的解释。
  • 这似乎不起作用,我得到了所有行的唯一计数。事实上,我没有看到按列过滤的尝试。
  • 密钥 $2 和 $3 是多余的,但如果您删除它们,您会得到我已经发布的内容。
  • @tripleee 密钥不是多余的,它们是必需的 ($1) 在前两个条件不满足的情况下可能已经存在,这可能会让你错过。如果cond1cond1 && cond2 的表达式中失败(或者存在吗?),则没有任何内容表明不应评估cond2
【解决方案2】:

这是一个简单的 Awk 脚本。

awk -F '|' '$2=="456" && $3=="789" { if (!a[$1]++) count++ }
    END { print count }' file

您的示例数据在第 1 列中包含 5 个具有这些约束的不同值。

如果你想将值作为参数传递,

c2="456"
c3="789"
awk -F '|' -v col2="$c2" -v col3="$c3" '$2==col2 && $3==col3 {
        if (!a[$1]++) count++ }
    END { print count }' file

数组a 从我们已经看到的第 1 列收集键。如果数组不包含第一列的值,我们将 1 加到 count

【讨论】:

    【解决方案3】:

    使用grep'n cut'n sort'n wc'n 一堆管道:

    $ grep ^[^\|]*\|456\|789\| file | cut -d \| -f 1-3 | sort -u | wc -l
    5
    

    演示:

    $ grep ^[^\|]*\|456\|789\| file  # search for ^...|456|789|
    123|456|789|234
    456|456|789|2345
    124|456|789|2345
    125|456|789|2345
    126|456|789|2345
    

    并将其传送到

    cut -d \| -f 1-3               # to lose the last field
    123|456|789
    456|456|789
    124|456|789
    125|456|789
    126|456|789
    

    继续

    sort -u                        # sort and get unique records
    123|456|789
    124|456|789
    125|456|789
    126|456|789
    456|456|789
    

    最后

    wc -l                          # count them
    5
    

    超级马里奥的日常面包:

    |
    

    【讨论】:

    • 有了固定的列你可以做grep "|456|789|" file | cut -d"|" -f1 | sort -u | wc -l
    【解决方案4】:

    你可以试试 Perl

    perl -lne ' /^(.+?)\|(.+?)\|(.+?)\|/ and $2==456 and $3==789 and $kv{$1}++ ; END { print scalar keys %kv } ' 
    

    使用给定的输入

    $ cat vijiy.txt
    123|456|789|234
    456|456|789|2345
    124|456|789|2345
    125|456|789|2345
    126|456|789|2345
    128|451|782|2345
    $ perl -lne ' /^(.+?)\|(.+?)\|(.+?)\|/ and $2==456 and $3==789 and $kv{$1}++ ; END { print scalar keys %kv } ' vijiy.txt
    5
    $
    

    【讨论】:

      【解决方案5】:

      与之前的 awk 解决方案的逻辑略有不同。不过比也略:

      awk -F '|' '($2!=246 || $3!=789){next}!a[$1]++{c++}END{print c}' file
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-14
        • 2012-11-10
        • 2023-03-28
        • 1970-01-01
        • 1970-01-01
        • 2017-10-25
        • 1970-01-01
        相关资源
        最近更新 更多