Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 查找列中唯一值的数目_Linux - Fatal编程技术网

Linux 查找列中唯一值的数目

Linux 查找列中唯一值的数目,linux,Linux,我想知道使用linux命令列中唯一值的计数。该列的值如下所示(数据是根据以前的值编辑的)。我需要忽略最后的.M、.Q和.A,只计算植物的唯一数量 "series_id":"ELEC.PLANT.CONS_EG_BTU.56855-ALL-ALL.M" "series_id":"ELEC.PLANT.CONS_EG_BTU.56855-ALL-ALL.Q" "series_id":"ELEC.PLANT.CONS_EG_BTU.56855-WND-ALL.A" "series_id":"ELEC.

我想知道使用linux命令列中唯一值的计数。该列的值如下所示(数据是根据以前的值编辑的)。我需要忽略最后的.M、.Q和.A,只计算植物的唯一数量

"series_id":"ELEC.PLANT.CONS_EG_BTU.56855-ALL-ALL.M"
"series_id":"ELEC.PLANT.CONS_EG_BTU.56855-ALL-ALL.Q"
"series_id":"ELEC.PLANT.CONS_EG_BTU.56855-WND-ALL.A"
"series_id":"ELEC.PLANT.CONS_EG_BTU.56868-LFG-ALL.Q"
"series_id":"ELEC.PLANT.CONS_EG_BTU.56868-LFG-ALL.A"
"series_id":"ELEC.PLANT.CONS_EG_BTU.56841-WND-WT.Q"
"series_id":"ELEC.CONS_TOT.COW-GA-2.M"
"series_id":"ELEC.CONS_TOT.COW-GA-94.M"
我已经尝试过这个代码,但我无法避免这些后缀

cat ELEC.txt | grep 'series_id' | cut -d, -f1 | wc -l

对于上面的示例,预期计数应该是6,但我得到8,这应该可以完成工作:

grep-Po“ELEC.PLANT.*”文件| cut-d-f-4 |排序| uniq-c

  • 你第一次为“电子植物”那一部分
  • 删除.Q,A,M
  • 使用
    sort | uniq-c
  • 编辑: 对于新数据,只需执行以下操作:
    grep-Po“ELEC.*”文件| cut-d-f-4 | sort | uniq-c

    我计算唯一值的标准方法是确保我有值列表(在您的情况下使用
    grep
    cut
    ),并在管道后面添加以下命令:

    | sort -n | uniq -c
    

    sort
    根据数字排序进行排序,而
    uniq
    获取唯一的条目(
    -c
    代表“计数”)。

    执行此操作:
    cat ELEC.txt | grep'series|u id'| cut-f1-4-duniq | wc-l


    -f1-4
    将删除每行的第四个

    以下是使用
    awk
    的可能解决方案:

    awk 'BEGIN{FS="[:.\"]+"} /^"series_id":/{print $6}' \
    ELEC.txt |sort -n |uniq -c
    
    您发布的示例的输出如下所示:

      1 56841-WND-WT
      2 56855-ALL-ALL
      1 56855-WND-ALL
      2 56868-LFG-ALL
    
      1 ELEC.PLANT.CONS_EG_BTU.56841-WND-WT
      2 ELEC.PLANT.CONS_EG_BTU.56855-ALL-ALL
      1 ELEC.PLANT.CONS_EG_BTU.56855-WND-ALL
      2 ELEC.PLANT.CONS_EG_BTU.56868-LFG-ALL
    
    如果需要整个字符串,还可以打印其他字段:

    awk 'BEGIN{FS="[:.\"]+"; OFS="."} /^"series_id":/{print $3,$4,$5,$6}' \
    ELEC.txt |sort -n | uniq -c
    
    输出结果如下:

      1 56841-WND-WT
      2 56855-ALL-ALL
      1 56855-WND-ALL
      2 56868-LFG-ALL
    
      1 ELEC.PLANT.CONS_EG_BTU.56841-WND-WT
      2 ELEC.PLANT.CONS_EG_BTU.56855-ALL-ALL
      1 ELEC.PLANT.CONS_EG_BTU.56855-WND-ALL
      2 ELEC.PLANT.CONS_EG_BTU.56868-LFG-ALL
    

    当您必须进行一些计数时,您可以使用
    awk
    轻松完成。Awk是一个非常通用的工具,我强烈建议您看看它。也许从一开始

    话虽如此,您可以在此处轻松进行条件计数:

    您需要的是计算其中包含
    series\u id
    的所有唯一行

    awk '/series_id/ && (! $0 in a) { c++; a[$0] } END {print c}'
    
    这本质上是这样的:如果我的行包含“series_id”,并且我没有将该行存储在数组
    a
    中,那么这意味着我还没有遇到我的行,并将计数器
    c
    增加为1。在程序结束时,我打印计数
    c

    现在你想把事情弄清楚一点。你的兴趣线基本上看起来像

    "something":"something else" 
    
    因此,如果
    是一个字段分隔符,那么我们感兴趣的是第四个字段中的
    其他东西,并且我们只感兴趣的是,如果
    某个东西
    是位于字段2中的
    序列id

    awk -F'"' '($2=="series_id") && (! $4 in a ) { c++; a[$4] } END {print c}'
    
    最后,您不关心第四个字段的最后一个字母,因此我们需要做一个小的替换:

    awk -F'"' '($2=="series_id") { str=$4; gsub(/.$/,"",str); if (! str in a) {c++; a[str] } } END {print c}'
    
    您也可以将其改写为:

    awk -F'"' '($2 != "series_id" ) { next }
               { str=$4; gsub(/.$/,"",str) }
               ( str in a ) { next }
               { c++; a[str] }
               END { print c }'
    

    cat
    不是真正需要的。问题是关于获取
    uniq
    值,而不是
    cat
    grep
    是的,但这并不意味着以这种方式使用
    cat
    是一种好的做法。你能建议修复上面编辑的数据吗?使用
    uniq
    删除重复项,使用
    -f1-4
    删除
    .M
    .Q
    .A
    每行。请参阅下面我的解决方案。我可以知道如何修复新数据吗?@Prajwal您应该修改(或删除)命令的
    grep
    部分。在编辑的数据中,最后两行只有三个点。因此“-f-4”似乎不起作用entirely@Prajwal:你是什么意思?