In cột cuối cùng của một dòng trong một tệp


135

Tôi có một tập tin liên tục được ghi vào / cập nhật. Tôi muốn tìm dòng cuối cùng chứa một từ cụ thể, sau đó in cột cuối cùng của dòng đó.

Các tập tin trông giống như thế này. Nhiều dòng A1 / B1 / C1 sẽ được thêm vào theo thời gian.

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

Tôi đã thử sử dụng

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

để in giá trị 766, nhưng không có gì là đầu ra.

Có cách nào để làm việc này không?

Câu trả lời:


199

Bạn không thấy gì cả, vì bộ đệm. Đầu ra được hiển thị, khi có đủ dòng hoặc cuối tập tin. tail -fcó nghĩa là chờ thêm đầu vào, nhưng không có thêm dòng nào filevà vì vậy đường ống grepkhông bao giờ bị đóng.

Nếu bạn bỏ qua -ftừ tailđầu ra được hiển thị ngay lập tức:

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

@EdMorton là tất nhiên. Awk cũng có thể tìm kiếm A1, rút ​​ngắn dòng lệnh thành

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

hoặc không có đuôi, hiển thị cột cuối cùng của tất cả các dòng chứa A1

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

Nhờ nhận xét của @ MitchellTracy, tailcó thể bỏ lỡ bản ghi có chứa A1và do đó bạn không nhận được kết quả đầu ra nào cả. Điều này có thể được giải quyết bằng cách chuyển đổi tailawk, tìm kiếm đầu tiên thông qua tệp và chỉ sau đó hiển thị dòng cuối cùng:

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

14
Bạn không bao giờ cần grep + awk vì awk có thể tự so sánh RE. "grep A1 | awk '{print $ NF}'" chỉ nên là "awk '/ A1 / {print $ NF}'". Ngoài ra, nếu bạn không sử dụng đuôi -f thì bạn hoàn toàn không cần đuôi, yoiu chỉ có thể làm: awk '/ A1 / {f = $ NF} END {print f}'
Ed Morton

Điều này không hoàn toàn đúng, vì cột có thể không xuất hiện trong cửa sổ mà raw tailcung cấp cho bạn. Trừ khi bạn biết nó sẽ xuất hiện với một tần số nhất định, nó sẽ an toàn hơn awk '/A1/ {print $NF}' file | tail -n1.
Mitchell Tracy


12

Một cách sử dụng awk:

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

Tôi nghĩ rằng đó là giải pháp phù hợp cho vấn đề được đăng (+1!) Nhưng bây giờ tôi thấy tôi không hiểu câu hỏi. OP muốn trường cuối cùng từ LAST LINE của tệp, nhưng không có LAST LINE nếu bạn đang sử dụng đuôi -f. Có lẽ anh ta có nghĩa là dòng cuối cùng HIỆN TẠI trong tệp, trong trường hợp đó thấy một trong những ý kiến ​​khác của tôi.
Ed Morton

Rất tốt và đơn giản. Đồng ý. Đồng ý với awkcú pháp khó hiểu :)
stamster

11

Bạn có thể làm điều này mà không cần awk chỉ với một số đường ống.

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

Điều này giải quyết vấn đề của bạn, nhưng nó không thực sự sử dụng awk. Hy vọng nó đủ tốt cho bạn nào.
miono

4

có lẽ điều này làm việc?

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

2

Bạn có thể làm tất cả trong awk:

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

1
Bạn không cần split () và một mảng, chỉ cần lưu trường cuối cùng và in tệp đó: awk '/ A1 / {f = $ NF} END {print f}'
Ed Morton

2

Sử dụng 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

$

Trông quá phức tạp, cứ làm điperl -lane 'print $F[2] if /A1/' rayne.txt
Hi-Angel

1
@ Hi-Angel..câu hỏi về lần xuất hiện cuối cùng của A1. câu trả lời của bạn sẽ in tất cả các trận đấu .. btw nếu bạn thích câu trả lời của tôi, vui lòng upvote nó
stack0114106

1

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

Sử dụng awkvới dấu tách trường -F được đặt thành khoảng trắng "".

Sử dụng mẫu $1=="A1"hành động {print $NF} , thao tác này sẽ in trường cuối cùng trong mỗi bản ghi trong đó trường đầu tiên là "A1". Đưa kết quả vào đuôi và sử dụng -n 1tùy chọn để chỉ hiển thị dòng cuối cùng.


0

Thực hiện điều này trên tập tin:

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

và bạn sẽ nhận được những gì bạn đang tìm kiếm.


0

Không phải vấn đề thực tế ở đây, nhưng có thể giúp một số người: Tôi đã làm awk "{print $NF}", lưu ý các trích dẫn sai. Nên awk '{print $NF}', để vỏ không mở rộng $NF.


-2

ls -l | awk '{print $9}' | tail -n1


1
Làm thế nào điều này thậm chí liên quan đến câu hỏi của OP?
Hickory420
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.