用unix sort、uniq和awk代替SQL查询



我们目前在HDFS集群上有一些数据,我们使用Hive在该集群上生成报告。基础设施正处于退役的过程中,我们剩下的任务是找到生成数据报告的替代方案(我们将数据作为tab分隔的文件导入到新环境中)

假设我们有一个包含以下字段的表。

    查询
  • IPAddress
  • LocationCode

我们用来在Hive上运行的原始SQL查询是(好吧,不完全是…但类似的东西)

select 
COUNT(DISTINCT Query, IPAddress) as c1,
LocationCode as c2, 
Query as c3
from table
group by Query, LocationCode

我想知道是否有人可以为我提供一个最有效的脚本,使用标准的unix/linux工具,如sort, uniq和awk,可以作为上述查询的替代品。

假设脚本的输入是一个文本文件目录。该目录将包含大约2000个文件。每个文件将包含任意数量的以制表符分隔的记录,格式为:

Query <TAB> LocationCode <TAB> IPAddress <NEWLINE>

一旦你有了一个包含所有唯一的

的排序文件
Query <TAB> LocationCode <TAB> IPAddress <NEWLINE>

你可以:

awk -F 't' 'NR == 1 {q=$1; l=$2; count=0}
q == $1 && l == $2{count++}
q != $1 || l != $2{printf "%st%st%dn", q, l, count; q=$1; l=$2; count=1}
END{printf "%st%st%dn", q, l, count}' sorted_uniq_file

要得到这个sorted_uniq_file,朴素的方法可以是:

sort -u dir/* > sorted_uniq_file

但是这可能会很长且占用内存。

一个更快的选择(和更少的内存消耗)可能是尽快消除重复,先排序,然后合并。这需要一个临时空间来存放已排序的文件,让我们使用一个名为sorted的目录:

mkdir sorted;
for f in dir/*; do
   sort -u $f > sorted/$f
done
sort -mu sorted/* > sorted_uniq_file
rm -rf sorted

如果上述解达到壳极限或排序极限(dir/*的展开式,或sorted/*的展开式,或sort的参数个数):

mkdir sorted;
ls dir | while read f; do
   sort -u dir/$f > sorted/$f
done
while [ `ls sorted | wc -l` -gt 1 ]; do
  mkdir sorted_tmp
  ls sorted | while read f1; do
    if read f2; then
      sort -mu sorted/$f1 sorted/$f2 > sorted_tmp/$f1
    else
      mv sorted/$f1 sorted_tmp
    fi
  done
  rm -rf sorted
  mv sorted_tmp sorted
done
mv sorted/* sorted_uniq_file
rm -rf sorted

上面的解决方案可以优化为同时合并两个以上的文件

不是直接回答你原来的问题(你已经得到),但如果你有一堆平面文件数据,你想以不同的方式查询,你可以考虑使用NoSQL:

http://www.strozzi.it/cgi-bin/CSA/tw7/I/en_US/nosql/Home%20Page

这个NoSQL项目与最近被称为"NoSQL数据库"的项目完全不同(并且早了许多年)。相反,这种NoSQL将以Awk为核心的Unix工具捆绑在一起,以简化它们在访问和维护格式化文本文件数据库时的使用。

最新更新