0

access.logサーバー上のファイルをダイジェストする 3 つの関数があります。

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
}

それらはすべて、単独で使用すると正常に機能します。3 つすべてが 2 つの小さな列のデータを出力します。

今、私は別の関数を作成しようとしています。この関数は、最初の 3 つの関数の結果であるヘッダー付きの 3 列のデータを出力するための書式設定機能reportを単純に使用します。printfそんな感じ:

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

問題は、フォーマットが私が望むものではないということです。列を並べてではなく、水平に印刷します。

どんな助けでも大歓迎です。

4

1 に答える 1

3

を使用pasteして 3 つのコマンドの出力を 1 つのストリームに結合すると、ごとに操作してそれらの出力をフォーマットできます。

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によって作成されます)。の使用の詳細については、 BashFAQ #1を参照してくださいread
  • 引数に引用符を付けると、引用符なしの値として文字列分割とグロブ展開の対象になるのではなく、によって組み立てられた各値が単一の値としてにprintf確実に渡されます。readprintf
于 2015-07-20T14:40:26.927 に答える