การพิมพ์คอลัมน์สุดท้ายของบรรทัดในไฟล์


136

ฉันมีไฟล์ที่กำลังเขียน / อัปเดตอยู่ตลอดเวลา ฉันต้องการค้นหาบรรทัดสุดท้ายที่มีคำใดคำหนึ่งจากนั้นพิมพ์คอลัมน์สุดท้ายของบรรทัดนั้น

ไฟล์มีลักษณะดังนี้ บรรทัด A1 / B1 / C1 เพิ่มเติมจะถูกต่อท้ายเมื่อเวลาผ่านไป

A1 123 456
B1 234 567
C1 345 678
A1 098 766
B1 987 6545
C1 876 5434

ฉันพยายามที่จะใช้

tail -f file | grep A1 | awk '{print $NF}'

เพื่อพิมพ์ค่า 766 แต่ไม่มีผลลัพธ์ใด ๆ

มีวิธีทำไหม?

คำตอบ:


201

คุณไม่เห็นอะไรเลยเพราะการบัฟเฟอร์ ผลลัพธ์จะปรากฏขึ้นเมื่อมีบรรทัดหรือจุดสิ้นสุดของไฟล์เพียงพอ tail -fหมายถึงรอการป้อนข้อมูลเพิ่มเติม แต่ไม่มีเส้นเข้าอีกfileดังนั้นท่อที่grepจะไม่ปิด

หากคุณละเว้น-fจากtailผลลัพธ์จะแสดงทันที:

tail file | grep A1 | awk '{print $NF}'

@EdMorton ถูกต้องแน่นอน Awkสามารถค้นหาได้A1เช่นกันซึ่งจะทำให้บรรทัดคำสั่งสั้นลงเป็น

tail file | awk '/A1/ {print $NF}'

หรือไม่มีหางแสดงคอลัมน์สุดท้ายของบรรทัดทั้งหมดที่มี A1

awk '/A1/ {print $NF}' file

ขอบคุณความคิดเห็นของ @MitchellTracy tailอาจพลาดบันทึกที่มีA1และทำให้คุณไม่ได้รับผลลัพธ์เลย สิ่งนี้อาจแก้ไขได้โดยการสลับtailและawkค้นหาไฟล์ก่อนจากนั้นจึงแสดงบรรทัดสุดท้ายเท่านั้น:

awk '/A1/ {print $NF}' file | tail -n1

15
คุณไม่จำเป็นต้องใช้ grep + awk เนื่องจาก awk สามารถทำการเปรียบเทียบ RE ของตัวเองได้ "grep A1 | awk" {print $ NF} "" ควรเป็น "awk" / A1 / {print $ NF} "" นอกจากนี้หากคุณไม่ได้ใช้ tail -f คุณก็ไม่จำเป็นต้องใช้ tail เลย yoiu ก็ทำได้: awk '/ A1 / {f = $ NF} END {print f}' file
Ed Morton

1
สิ่งนี้ไม่ถูกต้องนักเนื่องจากคอลัมน์อาจไม่ปรากฏในหน้าต่างที่tailให้ข้อมูลดิบแก่คุณ awk '/A1/ {print $NF}' file | tail -n1ถ้าคุณรู้ว่ามันเป็นไปได้ที่ปรากฏขึ้นพร้อมกับความถี่บางอย่างก็จะปลอดภัยในการ
Mitchell Tracy


12

วิธีเดียวโดยใช้awk:

tail -f file.txt | awk '/A1/ { print $NF }'

ฉันคิดว่านั่นเป็นวิธีแก้ปัญหาที่ถูกต้องสำหรับปัญหาที่โพสต์ (+1!) แต่ตอนนี้ฉันเห็นว่าฉันไม่เข้าใจคำถาม OP ต้องการฟิลด์สุดท้ายจาก LAST LINE ของไฟล์ แต่ไม่มี LAST LINE หากคุณใช้ tail -f บางทีเขาอาจหมายถึงบรรทัดสุดท้ายในปัจจุบันในไฟล์ซึ่งในกรณีนี้ให้ดูความคิดเห็นอื่น ๆ ของฉัน
Ed Morton

ดีมากและเรียบง่าย ยกนิ้วให้ ยกนิ้วให้กับawkไวยากรณ์ที่เป็นความลับของ :)
stamster

11

คุณสามารถทำได้โดยไม่ต้องใช้ awk ด้วยท่อเพียงบางส่วน

tac file | grep -m1 A1 | rev | cut -d' ' -f1 | rev

วิธีนี้ช่วยแก้ปัญหาของคุณได้ แต่ไม่ได้ใช้ awk จริงๆ หวังว่าจะดีพอสำหรับคุณต่อไป
miono


2

คุณสามารถทำได้ทั้งหมดในawk:

<file awk '$1 ~ /A1/ {m=$NF} END {print m}'

1
คุณไม่จำเป็นต้องแยก () และอาร์เรย์เพียงแค่บันทึกช่องสุดท้ายแล้วพิมพ์ว่า: awk '/ A1 / {f = $ NF} END {print f}' file
Ed Morton

2

ใช้ Perl

$ cat rayne.txt
A1 123 456
B1 234 567
C1 345 678
A1 098 766
B1 987 6545
C1 876 5434


$ perl -lane ' /A1/ and $x=$F[2] ; END { print "$x" } ' rayne.txt
766

$

ดูซับซ้อนเกินไปเพียงแค่ทำperl -lane 'print $F[2] if /A1/' rayne.txt
Hi-Angel

1
@ ไฮแองเจิ้ล.. คำถามถามถึง A1 ครั้งสุดท้าย คำตอบของคุณจะพิมพ์การแข่งขันทั้งหมด .. btw ถ้าคุณชอบคำตอบของฉันโปรดเพิ่มคะแนน
stack0114106

1

awk -F " " '($1=="A1") {print $NF}' FILE | tail -n 1

ใช้awkกับตัวคั่นช่อง-Fกำหนดช่องว่าง ""

ใช้รูปแบบ $1=="A1"และการกระทำ {print $NF}ซึ่งจะพิมพ์ฟิลด์สุดท้ายในทุกระเบียนโดยที่ฟิลด์แรกคือ "A1" บีบผลลัพธ์เป็นหางและใช้-n 1ตัวเลือกเพื่อแสดงเฉพาะบรรทัดสุดท้าย


0

ดำเนินการกับไฟล์:

awk 'ORS=NR%3?" ":"\n"' filename

และคุณจะได้รับสิ่งที่คุณกำลังมองหา


0

ไม่ใช่ปัญหาจริงที่นี่ แต่อาจช่วยได้บ้าง: ฉันกำลังทำอยู่awk "{print $NF}"โปรดสังเกตคำพูดที่ไม่ถูกต้อง ควรจะเป็นเพื่อให้เปลือกไม่ขยายawk '{print $NF}'$NF


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