Linux 查找列中唯一值的数目
我想知道使用linux命令列中唯一值的计数。该列的值如下所示(数据是根据以前的值编辑的)。我需要忽略最后的.M、.Q和.A,只计算植物的唯一数量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.
"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
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:你是什么意思?