0

我有三个函数可以消化access.log我服务器上的文件。

hitsbyip() {
        cat $ACCESSLOG | awk '{ print $1 }' | uniq -c | sort -nk1 | uniq
}
hitsbyhour() {
        cat $ACCESSLOG | cut -d[ -f2 | cut -d] -f1 | awk -F: '{print $2":00"}' | sort -n | uniq -c
}
hitsbymin() {
        hr=$1
        grep "2015:${hr}" $ACCESSLOG | cut -d[ -f2 | cut -d] -f1 | awk -F: '{print $2":"$3}' | sort -nk1 -nk2 | uniq -c
}

单独使用时,它们都可以正常工作。所有三个输出 2 小列数据。

现在我正在寻找创建另一个名为的函数report,它将简单地使用printf它的格式化可能性来打印带有标题的 3 列数据,每列都是我的三个第一个函数的结果。像这样的东西:

report() {
       printf "%-30b %-30b %-30b\n" `hitsbyip` `hitsbyhour` `hitsbymin 10`
}

问题是格式不是我想要的;它水平打印列而不是并排打印。

任何帮助将不胜感激。

4

1 回答 1

3

一旦您使用paste将三个命令的输出组合到一个流中,您可以逐行操作来格式化这些输出。

while IFS=$'\t' read -r by_ip by_hour by_min; do
  printf '%-30b %-30b %-30b\n' "$by_ip" "$by_hour" "$by_min"
done < <(paste <(hitsbyip) <(hitsbyhour) <(hitsbymin 10))

需要注意的元素:

  • <()语法是进程替换;它生成一个文件名(通常/dev/fd/##在具有此类支持的平台上的格式),当读取该文件名时,将产生给定命令的输出。
  • paste采用一系列文件名并将每个文件名的输出放在一起。
  • 读取时设置IFS=$'\t'确保我们将内容读取为制表符分隔值(格式paste创建)。有关使用. _read
  • 在参数上加上引号printf确保我们将每个组装的值read作为单个值传递给printf,而不是让它们作为不带引号的值进行字符串拆分和全局扩展。
于 2015-07-20T14:40:26.927 回答