たとえば、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
================================