AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 568639
Accepted
Kalpesh Bhoj
Kalpesh Bhoj
Asked: 2020-02-20 23:20:55 +0800 CST2020-02-20 23:20:55 +0800 CST 2020-02-20 23:20:55 +0800 CST

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

  • 772

我有一个名为 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
================================
awk text-formatting
  • 2 2 个回答
  • 61 Views

2 个回答

  • Voted
  1. Best Answer
    guest
    2020-02-21T00:49:25+08:002020-02-21T00:49:25+08:00

    编辑:

    Ed Mortons的回答更好,请使用它。


    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动作中再次使用它,因此将其定义为函数可以避免重复
    • 1
  2. Ed Morton
    2020-02-21T14:31:35+08:002020-02-21T14:31:35+08:00
    $ 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
    ================================
    
    • 1

相关问题

  • 根据第一个逗号之前的匹配删除重复行数

  • 在另一个文件之后逐行追加行

  • 如何删除两行之间的单行

  • 重新排列字母并比较两个单词

  • 多行文件洗牌

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve