如果我打开了一个新问题,很抱歉,但它与上一个问题无关,因为现在我需要一个bash命令来分析输出。
我将query的输出存储在一个文件中,如下所示:
3277654321 333011123456789
3277654321 333015123456789
3277654321 333103123456789
3277654321 333201123456789
3291234567 333991123456789
3291234567 333991123456789
3291234567 333011123456789我需要一个bash命令来计算具有相同前5位数的field1和field2,并报告如下输出:
3277654321=4;33301=2;33310=1;33320=1
3291234567=3;33399=2;33301=1谢谢卢卡斯。
发布于 2015-01-18 03:19:29
对原始数据使用awk
你要找的是一份打破控制的报告。这一次,维基百科的词条在这个问题上没有多大帮助。示例数据显示为已排序;因此,此解决方案假定数据已排序(但如果数据未排序,则在awk脚本之前添加排序操作非常简单;哦,因为数据来自数据库,所以数据库管理系统可以很好地对数据进行排序)。
出于测试目的,我创建了一个包含以下内容的文件awk.script:
{ f1 = $1
f2 = substr($2, 1, 5)
if (oldf1 != f1)
{
if (oldf1 != 0)
{
summary = summary ";" oldf2 "=" f2_count
printf("%s=%d%s\n", oldf1, f1_count, summary)
}
oldf1 = f1
f1_count = 0
oldf2 = f2
f2_count = 0
summary = ""
}
else if (oldf2 != f2)
{
summary = summary ";" oldf2 "=" f2_count
oldf2 = f2
f2_count = 0
}
f1_count++
f2_count++
}
END {
if (oldf1 != 0)
{
summary = summary ";" oldf2 "=" f2_count
printf("%s=%d%s\n", oldf1, f1_count, summary)
}
}并将这七行样本数据放入名为data的文件中,然后运行:
$ awk -f awk.script data
3277654321=4;33301=2;33310=1;33320=1
3291234567=3;33399=2;33301=1
$让DBMS做更多的工作
目前,数据类似于查询的输出,例如:
SELECT Field1, Field2
FROM SomeTable
ORDER BY Field1, Field2通过让DBMS生成第一个字段、第二个字段的前5个字符和条目数计数,可以使输出更适合您的报表:
SELECT field1, SUBSTR(field2, 1, 5) AS field2, COUNT(*) AS number
FROM SomeTable
GROUP BY field1, field2
ORDER BY field1, field2这样就减少了通过网络传输的数据,如果数据库是远程的,这会有很大帮助。您还有一个更简单的报告。数据文件变为(data2):
3277654321 33301 2
3277654321 33310 1
3277654321 33320 1
3291234567 33399 2
3291234567 33301 1awk脚本变为(awk.script2):
{
if (oldf1 != $1)
{
if (oldf1 != 0)
printf("%s=%d%s\n", oldf1, f1_count, summary)
oldf1 = $1
f1_count = 0
summary = ""
}
summary = summary ";" $2 "=" $3
f1_count += $3
}
END {
if (oldf1 != 0)
printf("%s=%d%s\n", oldf1, f1_count, summary)
}示例运行:
$ awk -f awk.script2 data2
3277654321=4;33301=2;33310=1;33320=1
3291234567=3;33399=2;33301=1
$让DBMS做更多的工作
根据您的数据库管理系统以及它是否支持子查询中的GROUP_CONCAT和ORDER BY子句,您可以注意到rici suggested“它并没有那么凌乱”。
以下内容在SQLite3中似乎运行良好;对于MySQL,您需要在GROUP_CONCAT中将逗号更改为单词分隔符:
SELECT field1 || "=“|| SUM( count2 ) || ";”|| group_concat(field2 || "=“|| count2,";") AS field FROM (SELECT field1,SUBSTR( field2,1,5) AS field2,COUNT(*) AS count2 FROM tmp GROUP BY field1,field2 ORDER BY field1,field2) GROUP BY field1 ORDER BY field1
注意,据我所知,子查询中的GROUP_CONCAT和ORDER BY子句都不是由ISO标准SQL定义的,因此并不是所有的数据库管理系统都支持这些特性。(由于原因,ORDER BY功能被省略了,但推理不包括“正交性”的考虑。)
如果数据库管理系统以您需要的格式生成数据,则不需要awk脚本对其进行后处理。什么才是最好的,最终将取决于你还在做什么。通常,在有意义的地方使用DBMS进行计算。请不要使用数据库管理系统进行所有的格式化- I期望报告生成与分页等在数据库管理系统之外完成-但如果可以说服它生成您需要的数据,请务必让它完成这项工作。
发布于 2015-01-18 15:34:28
朋友们,我想分享一个“优雅”的解决方案。感谢其他社区用户,他们为我提供了一些建议。
awk 'NR>0 {C1[$1]++
C2[$1,substr($2,1,5)]++
}
END {for (c2 in C2) {split (c2, cx, SUBSEP); print cx[1] "=" C1[cx[1]] ";" cx[2] "=" C2[c2]}}
' SUBSEP=";" out.txt | sort | awk '$1 != L {printf "%s%s", LT, $1; L=$1; LT="\n"}
{printf ";%s", $2}
END {printf "\n"}
' FS=";"
3277654321=4;33301=2;33310=1;33320=1
3291234567=3;33399=2;33301=1rici,这不是我要求别人为我写代码的情况。这只是一个大脚本中非常小的一部分,所以我只是请求帮助如何做一件小事情。我对不同的方法很感兴趣,这就是为什么我不提供任何代码示例的原因。感谢所有参与这个问题的SO用户,我仍然愿意尝试不同的方法。
https://stackoverflow.com/questions/28001979
复制相似问题