เพิ่มรายการค่าของคอลัมน์ A และ B คั่นด้วยช่องว่างและแสดงผลการสรุป [ซ้ำ]

Dec 29 2020

ฉันมีไฟล์ชื่อfold.txt. มีสองค่าในแต่ละบรรทัดคั่นด้วยช่องว่าง ถ้าฉันบอกว่าค่าแรกเป็นตัวแทนของคอลัมน์ A และค่าที่สองหลังจากเว้นวรรคคือคอลัมน์ B ฉันจะเพิ่มค่าทั้งหมดของคอลัมน์ A และค่าทั้งหมดของคอลัมน์ B และแสดงผลรวมของแต่ละคอลัมน์ทีละคอลัมน์ได้อย่างไร

ฉันคาดหวังสิ่งนี้:

$ cat fold.txt
100 500
200 300
700 100

เอาท์พุต:

Total count Column A = 1000
Total count column B = 900

คำตอบ

5 αғsнιη Dec 29 2020 at 00:00

ด้วยawk:

awk '{ sum_A +=$1; sum_B+=$2; };
END{ print "Total count Column A = " sum_A +0;
     print "Total count column B = " sum_B +0;
}' infile

ในภาษาawkซึ่งเป็นเครื่องมือสำหรับวัตถุประสงค์ในการประมวลผลข้อความ$1แทนค่าของคอลัมน์แรกแทนค่า$2ของคอลัมน์ที่สองสำหรับคอลัมน์$3ที่สามและอื่น ๆ และอีกอันที่พิเศษNFคือแทนค่าของคอลัมน์สุดท้ายและตาม$NFนั้นคือค่าของคอลัมน์สุดท้าย (เพื่อให้คุณสามารถแทนที่$2ด้านบนด้วย$NFเช่นกันและใช่คุณจับได้เมื่อNFเป็น Id คอลัมน์สุดท้ายดังนั้นค่าของตัวแปรจะบอกคุณว่าคุณมีคอลัมน์จำนวนเท่าใด (ค่าที่อัปเดตสำหรับแต่ละบรรทัด awk จะถูกอ่านจากอินพุต)

ในการจัดการกับขอบกรณีที่ไฟล์อินพุตว่างและยังคงได้รับเอาต์พุตตัวเลขเราจะเพิ่ม 0 ลงในผลลัพธ์awkเพื่อบังคับให้ส่งผลลัพธ์ที่เป็นตัวเลข

คอลัมน์ (หรือสาขา) ในawkโดดเด่นด้วยFSตัวแปร ( F eild S eparator) ซึ่งเริ่มต้นคือการใช้พื้นที่ / แท็บ หากคุณต้องการให้คอลัมน์แยกตามอักขระที่แตกต่างกันคุณสามารถกำหนดใหม่ได้ด้วย-Fตัวเลือกสำหรับawklike ใน:

awk -F'<character-here>' '...' infile

หรือภายในBEGIN{...}บล็อกเช่นFS:

awk 'BEGIN{ FS="<character-here>"; }; { ... }' infile

ตัวอย่างเช่นสำหรับไฟล์อินพุตเช่นด้านล่าง (ตอนนี้เป็นคอมมาแทนช่องว่าง):

100,500
200,300
700,100

คุณสามารถเขียนawkโค้ดของคุณได้ดังต่อไปนี้:

awk -F',' '{ sum_A +=$1; sum_B+=$2; };
END{ print "Total count Column A = " sum_A +0;
     print "Total count column B = " sum_B +0;
}' infile

หรือภายในBEGINบล็อก:

awk 'BEGIN{ FS=","; }; { sum_A +=$1; sum_B+=$2; };
END{ print "Total count Column A = " sum_A +0;
     print "Total count column B = " sum_B +0;
}' infile

ซับซ้อนเล็กน้อยและเพื่อรวมNคอลัมน์ทั้งหมดของไฟล์อินพุตของคุณในตัวอย่างต่อไปนี้:

100,500,140,400
200,300,640,200
700,100,400,130

ดังนั้นเราจึงพูดถึงNFในย่อหน้าแรก (ค่า NF บอกคุณว่าคุณมีคอลัมน์กี่คอลัมน์ (อัปเดตต่อแต่ละบรรทัด)):

awk -F',' '{ for (i=1; i<=NF; i++) sum[i]+=$i; };
END{ for (colId in sum) { 
         printf ("Total count Column: %d= %d\n", colId, sum[colId] );
     };
}' infile

สิ่งใหม่เพียงอย่างเดียวที่นี่คือเราใช้awkอาร์เรย์เพื่อระบุรหัสคอลัมน์เดียวกันโดยนำค่าiและเพิ่มค่า$iลงในอาร์เรย์นั้น (ดัชนี / คีย์ของอาร์เรย์นี้คือคอลัมน์ Ids) จากนั้นที่END{...}บล็อกเราวนซ้ำอาร์เรย์ของเราบนคีย์ที่เห็นจากนั้นพิมพ์รหัสคอลัมน์ก่อนจากนั้นผลรวมของสิ่งที่อยู่ข้างๆคุณจะเห็นผลลัพธ์ดังนี้:

Total count Column: 1= 1000
Total count Column: 2= 900
Total count Column: 3= 1180
Total count Column: 4= 730
ctac_ Dec 30 2020 at 01:56

เป็นงานที่ดีสำหรับ dc

dc อ่านข้อมูลจาก fold.txt ก่อนและหลังรหัสจาก sum_col_dc

ใช้แบบนั้น: dc fold.txt sum_col_dc

cat sum_col_dc  

[lB+sBlA+sAz0<C]sC[lGLElDnnnp]sH[Total count Column ]sD[B]sE[A]SE[ = ]sGlCxlAlHxlBlHx  

พร้อมรายละเอียดเพิ่มเติมเล็กน้อย:

[lB+sBlA+sAz0<C]sC  
[lGLElDnnnp]sH  
[Total count Column ]sD  
[B]sE  
[A]SE  
[ = ]sG  
lCx  
lA  
lHx  
lB  
lHx  

เพลิดเพลินกับ dc
เพิ่มเติมอธิบายตามความต้องการ