【问题标题】:Summarize list of hours and topics into per-hour matrix将小时和主题列表汇总到每小时矩阵中
【发布时间】:2021-02-18 04:42:18
【问题描述】:

我有一个如下文件:

9 0 topic1 hour=11
9 0 topic1 hour=12
9 0 topic1 hour=13
9 0 topic1 hour=14
9 0 topic1 hour=15
9 0 topic1 hour=16
9 0 topic1 hour=17
9 0 topic1 hour=18
9 0 topic1 hour=19
9 0 topic1 hour=20
9 0 topic1 hour=21
9 0 topic1 hour=22
9 0 topic1 hour=23
9 0 topic2 hour=00
9 0 topic2 hour=01
9 0 topic2 hour=02
9 0 topic2 hour=03
9 0 topic2 hour=04
9 0 topic2 hour=05
  • 第一列是最后一列的小时目录中的文件数
  • 第二列是以 GB 为单位的大小
  • 第三列是父 hdfs 目录
  • 最后一列是父目录中的每小时目录

我希望输出格式如下

            01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 
topic1      00 00 00 00 00 00 00 00 00 00 09 09 09 09 09 09 09 09 09 09 09 09 09 09  
topic2      09 09 09 09 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

这是每个父目录按小时计算的文件数,采用表格格式。如果可以在那里显示大小,比如用逗号分隔,那就太好了。

到目前为止,这是我设法创建的:

/bin/hdfs dfs -count <hdfs_path>/year=`date --date="1 days ago" +%Y`/month=`date --date="1 days ago" +%m`/day=`date --date="1 days ago" +%d`/*|awk '{print  $2, int($3/(1024*1024*1024)+0.5), $4}'|cut -d '/' -f1,5,9|sed 's/\// /g'| awk -v OFS='\t' '{print $1, $2, $3,"",$4}'|while read i
do
    for topic in topic1  topic2  topic3 
    do
        num_files=`echo $i|grep $topic|awk '{print  $1}'`
        size_gb=`echo $i|grep $topic|awk '{print  $2}'`
        hour=`echo $i|grep $topic|awk '{print  $4}'|cut -d "=" -f2`
    done        
done

我正在尝试解析每一行,然后格式化一个新行。考虑检查那里是否有其他聪明的方法。

我在 Linux 上,所以可以使用 Bash 或 Python。到目前为止,我设法创建的其余脚本是 Bash。

【问题讨论】:

    标签: linux bash shell awk


    【解决方案1】:

    如果您仍然使用 Awk,请使用它的功能。

    awk '{ t[$3]; k[$3 ":" $4] += $1; s[$3 ":" $4] += $2; next }
      END {
        printf "%-11s", ""; for (h=0; h<=24; h++) printf "   %02i", h; printf "\n"
        for (d in t) {
          printf "%-11s", d;
          for (h=0; h<=24; h++)
          { hh = sprintf("%02i", h);
            printf " %02i,%i", k[d ":hour=" hh], s[d ":hour=" hh]
          }
          printf "\n"
        }
      }' topics
    

    样本输出:

                  00   01   02   03   04   05   06   07   08   09   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24
    topic1      00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 09,0 09,0 09,0 09,0 09,0 09,0 09,0 09,0 09,0 09,0 09,0 09,0 09,0 00,0
    topic2      09,0 09,0 09,0 09,0 09,0 09,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0 00,0
    

    逻辑很简单;我们创建了一个关联数组k,其键是主题和小时,第二个数组t 仅包含主题,以便我们以后可以遍历每个主题。例如,k["topic2:hour=13"] 包含小时 13topic2 的值。同样,s["topic2:hour=13"] 包含该主题和小时的磁盘大小。最后,我们只需遍历主题和时间,然后提取并打印这些值。

    【讨论】:

    • 我已经设法将它与我的腻子提示符稍微相适应,只是格式化,但在我的知识水平上,你的代码有点高级。如果可能的话,请帮忙。第二个字段,应该是小时明智的。这应该让我知道昨天发生的事情,小时目录中的文件数量及其大小,所以大小不会改变。它是一个 kafka 转储到 hdfs,前一天运行,用于不同的主题。非常感谢!!!
    • 立即查看更新的答案。我也添加了一个简短的逻辑解释。
    • 我不确定一个小时是否可以为一个主题重复一次以上,所以这就是它添加这些值而不是覆盖的原因。如果我们可以确定每个条目都是唯一的,您可以使用 = 而不是 +=
    • 这就像一个魅力!非常感谢您的解释,我将阅读更多关于 awk 数组的内容。再次感谢!!! @tripleee 回答了这个问题
    • 小时值不会重复
    猜你喜欢
    • 2011-07-09
    • 1970-01-01
    • 2016-08-27
    • 1970-01-01
    • 2019-10-11
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多