从通用数据文件创建单独的表格输出,并计算一些总计

从通用数据文件创建单独的表格输出,并计算一些总计

我有一个名为 data.txt 的管道分隔文本文件,例如...

Kalpesh|100|1
Kalpesh|500|1
Ramesh|500|1
Ramesh|500|1
Ramesh|500|1
Naresh|500|1
Ganesh|500|1
Ganesh|500|1
Ganesh|500|1
Ganesh|500|1

我正在使用awk如下脚本:

awk -F"|" 'BEGIN { ln=0;slno=0;pg=0; }
{
name=$1;
{
if (name !=x||ln > 50) #if same name repeates more than 50times then new page
{ 
tot=0;
pg++;
printf("\f");
print "PERSONS HAVING OUTSTANDING ADVANCE SALARY"
print "+==============================+"
print "|Sr.|   name   |Amount Rs.|Nos |"
print "+==============================+"
ln=0;
}
if (name!=x)
slno=1;tot+=$2;
{
printf ("|%3s|%10s|%10.2f|%4d|\n",slno,$1,$2,$3,tot,$4);
ln++;
slno++;
x=name;
 }
}
} END {
print "================================"
print "Total for",$1,slno,tot
print "================================"
print "\f" }' data.txt

这给出的结果如下

PERSONS HAVING OUTSTANDING ADVANCE SALARY
+==============================+
|Sr.|   name   |Amount Rs.|Nos |
+==============================+
|  1|   Kalpesh|    100.00|   1|
|  2|   Kalpesh|    500.00|   1|

PERSONS HAVING OUTSTANDING ADVANCE SALARY
+==============================+
|Sr.|   name   |Amount Rs.|Nos |
+==============================+
|  1|    Ramesh|    500.00|   1|
|  2|    Ramesh|    500.00|   1|
|  3|    Ramesh|    500.00|   1|

PERSONS HAVING OUTSTANDING ADVANCE SALARY
+==============================+
|Sr.|   name   |Amount Rs.|Nos |
+==============================+
|  1|    Naresh|    500.00|   1|

PERSONS HAVING OUTSTANDING ADVANCE SALARY
+==============================+
|Sr.|   name   |Amount Rs.|Nos |
+==============================+
|  1|    Ganesh|    500.00|   1|
|  2|    Ganesh|    500.00|   1|
|  3|    Ganesh|    500.00|   1|
|  4|    Ganesh|    500.00|   1|
================================
Total for Ganesh 5 2000
================================

我想要的输出就像

PERSONS HAVING OUTSTANDING ADVANCE SALARY
+==============================+
|Sr.|   name   |Amount Rs.|Nos |
+==============================+
|  1|   Kalpesh|    100.00|   1|
|  2|   Kalpesh|    500.00|   1|
================================
Total for Kalpesh 2 600
================================

PERSONS HAVING OUTSTANDING ADVANCE SALARY
+==============================+
|Sr.|   name   |Amount Rs.|Nos |
+==============================+
|  1|    Ramesh|    500.00|   1|
|  2|    Ramesh|    500.00|   1|
|  3|    Ramesh|    500.00|   1|
================================
Total for Ramesh 3 1500
================================

PERSONS HAVING OUTSTANDING ADVANCE SALARY
+==============================+
|Sr.|   name   |Amount Rs.|Nos |
+==============================+
|  1|    Naresh|    500.00|   1|
================================
Total for Naresh 1 500
================================

PERSONS HAVING OUTSTANDING ADVANCE SALARY
+==============================+
|Sr.|   name   |Amount Rs.|Nos |
+==============================+
|  1|    Ganesh|    500.00|   1|
|  2|    Ganesh|    500.00|   1|
|  3|    Ganesh|    500.00|   1|
|  4|    Ganesh|    500.00|   1|
================================
Total for Ganesh 5 2000
================================

答案1

编辑:

艾德·莫顿的回答更好,请使用它。


awk 'function print_entry(a,b,c,d) {
    k=split(c, ce, " ")
    split(d, dn, " ")
    for(i=1; i<=k; i++) {
        if(i%50==1) printf("\f%s\n%s\n%s\n%s\n",
            "PERSONS HAVING OUTSTANDING ADVANCE SALARY",
            "+==============================+",
            "|Sr.|   name   |Amount Rs.|Nos |",
            "+==============================+")
        printf("|%3s|%10s|%10.2f|%4d|\n",i,a,ce[i],dn[i])
    }
    print "================================"
    print "Total for",a,k,b
    print "================================"
    printf("\f")
}
BEGIN {FS="|"}
{
    if($1==name) {
        total+=$2
        entry=(entry " " $2)
        nos=(nos " " $3)
    }
    else {
        if(name) print_entry(name,total,entry,nos)
        name=$1
        total=$2
        entry=$2
        nos=$3
    }
}
END {if(name) print_entry(name,total,entry,nos)}' data.txt

主要逻辑:

  • 收集与姓名相关的信息 ( $1)
    • total$2将每个条目相加
    • entry$2保留每个条目的列表
    • nos$3保留每个条目的列表
  • 每次名称更改时,打印收集到的信息
    • 拆分条目列表,给出该名称的$2条目数,列表也被拆分(它应该具有相同的条目数)k$3
    • 从 1 ( i=1) 开始,打印每个条目
    • 如果i mod 50打印1一个标题 - 这将每五十个条目打印一个新标题
    • 然后打印总数

  • 该函数的使用print_entry使主要操作更清晰且更易于阅读,而且它在操作中再次使用END,因此将其定义为函数可以节省重复操作

答案2

$ cat tst.awk
BEGIN { FS="|" }
$1 != prev {
    if ( NR>1 ) {
        prtTail()
    }
    prtHead()
    srval = 0
    tot   = 0
    prev  = $1
}
{
    tot += $2
    printf "|%3s|%10s|%10.2f|%4d|\n", ++srval, $1, $2, $3
}
END { prtTail() }

function prtHead() {
    print "PERSONS HAVING OUTSTANDING ADVANCE SALARY"
    print "+==============================+"
    print "|Sr.|   name   |Amount Rs.|Nos |"
    print "+==============================+"
}

function prtTail() {
    print "================================"
    printf "Total for %s %d %d\n", prev, srval, tot
    print "================================"
    print ""
}

$ awk -f tst.awk file
PERSONS HAVING OUTSTANDING ADVANCE SALARY
+==============================+
|Sr.|   name   |Amount Rs.|Nos |
+==============================+
|  1|   Kalpesh|    100.00|   1|
|  2|   Kalpesh|    500.00|   1|
================================
Total for Kalpesh 2 600
================================

PERSONS HAVING OUTSTANDING ADVANCE SALARY
+==============================+
|Sr.|   name   |Amount Rs.|Nos |
+==============================+
|  1|    Ramesh|    500.00|   1|
|  2|    Ramesh|    500.00|   1|
|  3|    Ramesh|    500.00|   1|
================================
Total for Ramesh 3 1500
================================

PERSONS HAVING OUTSTANDING ADVANCE SALARY
+==============================+
|Sr.|   name   |Amount Rs.|Nos |
+==============================+
|  1|    Naresh|    500.00|   1|
================================
Total for Naresh 1 500
================================

PERSONS HAVING OUTSTANDING ADVANCE SALARY
+==============================+
|Sr.|   name   |Amount Rs.|Nos |
+==============================+
|  1|    Ganesh|    500.00|   1|
|  2|    Ganesh|    500.00|   1|
|  3|    Ganesh|    500.00|   1|
|  4|    Ganesh|    500.00|   1|
================================
Total for Ganesh 4 2000
================================

相关内容