在bash中生成报告

时间:2014-08-04 11:40:31

标签: bash awk

我正在尝试使用bash生成摘要报告。我的文本文件格式是这样的:

title:composer:price:musical pieces available:musical pieces sold

但是,在我的报告输出中应该是这样的:

Title       Composer   Price   PiecesAvail   PiecesSold   TotalProfit
Graham      Jack       20.00       10            2           40.00
Zack        Squall      4.00       5             3            7.00

任何人都能指出我正确的方向吗?我必须事先或在生成报告时计算总利润。

文本文件的示例在这里:

 Graham:Jack:20.00:10:2
 Jack:Squall:4.00:5:3
 Random - One:Jim:5.00:4:1
 RainyDay:Melissa:50.00:2:1

我还没想过如何计算总利润。

6 个答案:

答案 0 :(得分:2)

看看这是否是你需要的:

kent$  awk -F':' -v OFS="\t" 'BEGIN{print "Title","Composer", "Price", "PA","PS","TotalP"}{"$1=$1";$(NF+1)=$3*$NF}7' f|column -t -s'    '
Title         Composer  Price  PA  PS  TotalP
Graham        Jack      20.00  10  2   40
Jack          Squall    4.00   5   3   12
Random - One  Jim       5.00   4   1   5
RainyDay      Melissa   50.00  2   1   50
  • 我缩短了标题中的单词,你可以把完整的单词放在那里
  • 最后' 'ctrl-v tab
  • 我刚刚以Price * PieceSold
  • 执行的总利润

答案 1 :(得分:2)

Perl使用Text::Table救援:

#!/usr/bin/perl
use warnings;
use strict;

use Text::Table;

my $t = 'Text::Table'->new('Title',
                           'Composer',
                           'Price',
                           'Pieces Available',
                           'Pieces Sold',
                           'Total Profit',
                          );
while (<>) {
    my ($title, $composer, $price, $available, $sold) = split /:/;
    my $profit = sprintf '%.2f', $price * $sold;
    $t->add($title, $composer, $price, $available, $sold, $profit);
}

print $t;

答案 2 :(得分:1)

希望这会有所帮助:

如果您希望这样做,此脚本将读取文本文件并输出..

  • 文本文件中的每一行都进入一个名为$ line
  • 的变量
  • 它遍历每一行
  • 使用cut -d ":" -f XX它会从$ line变量
  • 中删除一个字段编号(用分隔符:分隔)
  • 然后我用bc来做aritmatic(使用let会失败,因为像20.00这样的数字会让它变得疯狂)
  • 然后最终通过函数和column管道输出,使其看起来很漂亮

<强> foo.sh:

#!/usr/bin/env bash
echo "title composer price avail sold total"
function output(){
while read line
do
    title="$(cut -d ":"  -f 1 <<<"$line")"
    composer="$(cut -d ":" -f 2 <<<"$line")"
    price="$(cut -d ":" -f 3 <<<"$line")"
    avail="$(cut -d ":" -f 4 <<<"$line")"
    sold="$(cut -d ":" -f 5 <<<"$line")"
    #debug:
    #echo "title:$title, composer:$composer, price=$price, avail=$avail, sold=$sold" 
    total="$(echo "$price * $sold" | bc -l)"
    echo "$title $composer $price $avail $sold $total" 
done < file.txt
}
output | column -t

<强> file.txt的

Graham:Jack:20.00:10:2
Zack:Squall:4.00:5:3

然后你会这样称呼它:

stark@fourier ~ $ ./foo.sh
title   composer  price  avail  sold  total
Graham  Jack      20.00  10     2     40.00
Zack    Squall    4.00   5      3     12.00

答案 3 :(得分:1)

漂亮的打印列可能很繁琐,特别是如果事先不知道每个字段的最大长度。您可以在awk中使用printf来完成足够合理的工作:

awk -F: 'BEGIN { printf "%12s%12s%8s%12s%12s\n", "Title","Composer","Price","PiecesAvail","PiecesSold"
}
{ printf "%12s%12s%8s%12s%12s\n",$1,$2,$3,$4,$5 }' file

我已使用开关-F:将冒号指定为字段分隔符。

BEGIN块打印标题,每隔一行使用相同的格式打印。格式%Ns指定填充为N个字符的字符串,因此可用于固定宽度输出。

我没有计算您的总利润,但可以作为额外的列添加。例如,它就像Price * PiecesSolid一样简单,那就是$3*$5(第3列乘以第5列)。要将其显示为带有两位小数的数字,您可以将%.2f添加到printf语句的末尾。

答案 4 :(得分:1)

awk -F':' '
BEGIN {
    fmt = "%-15s%-11s%5s   %11s   %10s   %11s\n"
    printf fmt, "Title","Composer","Price","PiecesAvail","PiecesSold","TotalProfit"
}
{ printf fmt, $1,$2,$3,$4"     ",$5"     ",sprintf("%.2f   ",$3*$5) }
' file
Title          Composer   Price   PiecesAvail   PiecesSold   TotalProfit
Graham         Jack       20.00       10            2           40.00    
Jack           Squall      4.00        5            3           12.00    
Random - One   Jim         5.00        4            1            5.00    
RainyDay       Melissa    50.00        2            1           50.00  

答案 5 :(得分:0)

#!/bin/sh
awk -- 'BEGIN {
    FS = ":"
    OFS = "||"
    print "Title", "Composer", "Price", "PiecesAvail", "PiecesSold", "TotalProfit"
}
{
    sub(/^[ \t]+/, "", $1); sub(/\r+$/, "", $5)
    printf "%s||%s||%5.2f||%6d||%6d||%8.2f\n", $1, $2, $3, $4, $5, $5 * $3
}' "$@" | column -t -s '||'

用法

sh script.sh file

输出:

Title           Composer    Price    PiecesAvail    PiecesSold    TotalProfit
Graham          Jack        20.00        10              2           40.00
Jack            Squall       4.00         5              3           12.00
Random - One    Jim          5.00         4              1            5.00
RainyDay        Melissa     50.00         2              1           50.00