공통 데이터 파일에서 별도의 테이블 출력을 만들고 일부 합계를 계산합니다.

공통 데이터 파일에서 별도의 테이블 출력을 만들고 일부 합계를 계산합니다.

예를 들어 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- 항목 50개마다 새 제목이 인쇄됩니다.
    • 그런 다음 합계를 인쇄하십시오.

  • 이 함수를 사용하면 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
================================

관련 정보