พิมพ์คอลัมน์ / ฟิลด์สุดท้ายที่สองใน awk


164

ฉันต้องการพิมพ์คอลัมน์หรือฟิลด์สุดท้ายที่สองใน awk จำนวนฟิลด์เป็นตัวแปร ฉันรู้ว่าฉันควรใช้งาน$NFได้ แต่ไม่แน่ใจว่าจะใช้งานได้อย่างไร

และนี่ดูเหมือนจะไม่ทำงาน:

awk ' { print ( $NF-- )  } '

10
NFคือดัชนีฟิลด์สุดท้าย$NFคือค่าของฟิลด์สุดท้าย
glenn jackman

ที่เหมาะสมตอนนี้ นั่นเป็นเหตุผลว่าทำไมเงินดอลล่าร์ที่อยู่นอกวงเล็บผมจึงคิดว่า
Brian G

คำตอบ:


279
awk '{print $(NF-1)}'

ควรทำงาน


2
สิ่งนี้ไม่ได้ผลสำหรับฉัน ฉันได้รับ "ชื่อเรื่อง: 5: ไม่พบคำสั่ง: NF-1" ใน awk 3.1.8 ภายใต้ Ubuntu
Gurgeh

3
ฉันจะหลีกเลี่ยงการลดลงล่วงหน้า / โพสต์เพื่อให้แน่ใจว่าคุณจะไม่เปลี่ยนค่าของ $ NF
Gregory Patmore

สิ่งนี้จะหยุดถ้าคุณพยายามที่จะได้สนามที่สามเช่นawk -F '.' '{print $(NF-2)}'
gies0r

3
@Gurgeh: สิ่งนี้เกิดขึ้นเนื่องจาก$(..)เรียกใช้คำสั่งในเชลล์ย่อยซึ่งขึ้นอยู่กับเชลล์ที่คุณใช้ คุณสามารถทำงานรอบนี้โดยใช้แทน$ (NF-1) $(NF-1)
wting

21

คำตอบที่ยอมรับของ Chris Kannon น้อยมาก: พิมพ์เฉพาะในกรณีที่มีคอลัมน์สุดท้ายที่สอง

(
echo       | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1     | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1 2   | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1 2 3 | awk 'NF && NF-1 { print ( $(NF-1) ) }'
)

15

มันง่ายที่สุด:

 awk '{print $--NF}' 

เหตุผลที่ต้นฉบับ$NF--ไม่ทำงานเนื่องจากนิพจน์ได้รับการประเมินก่อนการลดลงในขณะที่การลดค่านำหน้าของฉันจะดำเนินการก่อนการประเมิน


เป็นตัวช่วยจำพฤติกรรมนี้เหมือนกับ C / Java เป็นต้นint x = ++i int x = i++คำนำหน้าหมายถึงการเพิ่มขึ้นก่อน postfix หมายถึงการเพิ่มขึ้นภายหลัง (การมอบหมายก่อน)
วันหยุดสุดสัปดาห์


4

คุณไม่ไกลจากผลลัพธ์! นี่มัน:

awk '{NF--; print $NF}' file

นี้ decrements จำนวนของเขตข้อมูลในหนึ่งเพื่อให้$NFมีอดีตสุดท้าย

ทดสอบ

มาสร้างตัวเลขกันบ้างแล้วพิมพ์ลงบนกลุ่มละ 5:

$ seq 12 | xargs -n5
1 2 3 4 5
6 7 8 9 10
11 12

ลองพิมพ์ penultimate ในแต่ละบรรทัด:

$ seq 12 | xargs -n5 | awk '{NF--; print $NF}'
4
9
11

3

โซลูชัน Perl คล้ายกับโซลูชัน awk ของ Chris Kannon:

perl -lane 'print $F[$#F-1]' file

ใช้ตัวเลือกบรรทัดคำสั่งเหล่านี้:

  • n วนรอบทุกบรรทัดของไฟล์อินพุตอย่าพิมพ์ทุกบรรทัดโดยอัตโนมัติ

  • l ลบบรรทัดใหม่ก่อนการประมวลผลและเพิ่มพวกเขากลับมาในภายหลัง

  • aโหมด autosplit - แบ่งบรรทัดอินพุตออกเป็น@Fอาร์เรย์ ค่าเริ่มต้นที่จะแยกในช่องว่าง

  • e รันรหัส Perl

@Fอาร์เรย์ AutoSplit เริ่มต้นที่ดัชนี [0] ในขณะที่เขต awk เริ่มต้นด้วย $ 1
$#Fคือจำนวนองค์ประกอบใน@F


1
หรือใช้การจัดทำดัชนีเชิงลบที่มีให้บริการแล้วโดย Perl ...$F[-2]
Sundeep

2

คุณพยายามเริ่มจากขวาไปซ้ายโดยใช้คำสั่ง rev หรือไม่ ในกรณีนี้คุณเพียงแค่พิมพ์คอลัมน์ที่ 2:

seq 12 | xargs -n5 | rev | awk '{ print $2}' | rev
4
9
11


0

หากคุณมีคอลัมน์จำนวนมากและต้องการพิมพ์ทั้งหมด แต่ไม่ใช่ทั้งสาม cloumns ในครั้งสุดท้ายสิ่งนี้อาจช่วยได้

awk '{ $NF="";$(NF-1)="";$(NF-2)="" ; print $0 }'

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.