Làm cách nào tôi có thể đếm số dòng trong một tệp sau khi khớp grep?


14

Tôi đang cố gắng đếm số dòng sau một hàng có vấn đề trong tệp csv. Tôi biết rằng tôi có thể sử dụng grep -a #cú pháp để xuất # số dòng sau khi kết quả khớp được tìm thấy. Tôi chỉ quan tâm đến số lượng dòng thực tế. Tôi nhận ra rằng tôi có thể đặt số thành MAX_INT, chuyển nó thành một tệp và xử lý thêm.

Tôi đang tìm kiếm một lớp lót ngắn gọn để chỉ cho tôi biết số đếm.

Bất kỳ đề xuất?

Câu trả lời:


15
{ grep -m1 match; grep -c ''; } <file

Điều đó sẽ làm việc với GNU grepvà một lseek()infile có thể. Cái đầu tiên grepsẽ dừng ở 1 -match, và cái thứ hai sẽ -cđếm từng dòng còn lại trong đầu vào.

Không có GNU grep:

{ sed '/match/q'; grep -c ''; } <file

Tất nhiên, w / grepbạn có thể sử dụng bất kỳ / tất cả các tùy chọn khác của nó bên cạnh, và dừng lại ở một trận đấu là không cần thiết.


Cả hai cũng in dòng, và cái thứ hai in lên đến trận đầu tiên và sau đó là 0 cho tôi?
123

@ User112638726 - dĩ nhiên bạn có thể bỏ bản in của trận đấu đầu tiên grep -m1 match >/dev/null. Và vấn đề thứ hai của bạn là GNU sed- nó không thiết lập lại phần bù đầu vào cho mỗi thông số. Bạn phải sử dụng -uw / GNU - điều không phải lúc nào cũng mong muốn. Tôi có thể đã rõ ràng hơn, nhưng giả định của tôi là GNU grepvà GNU sedsẽ đi theo cặp. Tôi nghĩ, cũng grep -qm1có thể hoạt động để rút ngắn /dev/nullchuyển hướng - nhưng GNU grepthực hiện những điều kỳ lạ với -qtôi và tôi không thể nhớ lại cách hai thứ đó hoạt động cùng nhau.
mikeerv

1
Câu trả lời hay - thực sự thể hiện sức mạnh của các nhóm chỉ huy. Tôi không biết chắc chắn, nhưng tôi đoán wc -llà rẻ hơn một chút so với grep -c ''.
Chấn thương kỹ thuật số

1
@DigitalTrauma - Vâng, tôi đã xem xét nó (khi nhìn lại) , nhưng tôi đã viết nó và nó gần như có vần điệu, vì vậy tôi nghĩ rằng tôi đã để một mình đủ tốt. Và dù sao, bạn cũng nói vậy, nên giờ tôi sẽ ngủ dễ dàng.
mikeerv

9

Đây là một cách.

$ cat foo
aaa
bbb
ccc
ddd
eee
fff
$ awk '/^ddd/{a=FNR}END{print FNR-a}' foo
2
$

4
đây không phải là codegolf, bạn có thể cung cấp chi tiết (FNR, END và vv) không?
Archemar

3
Chắc chắn rồi. awk sử dụng FNR để xác định số hồ sơ đầu vào. END là mã được thực thi khi đến cuối tập tin. Vì vậy, khi một trận đấu được tìm thấy, số kỷ lục hiện tại được ghi lại. Khi đến cuối tập tin, số đó sẽ được trừ vào tổng số dòng trong tệp.
steve

1
Có thể chỉ sử dụng NR vì nó là một tệp.
123

6

Một cách khác - sử dụng dclà một chút bí truyền, nhưng dường như hoạt động độc đáo ở đây:

sed -n '/problem/=;$=' prob.txt | dc -e '??r-p'

sedtìm kiếm prob.txt"vấn đề" và dòng cuối cùng, và sử dụng =lệnh để xuất số dòng của cả hai.

dc đọc hai giá trị này lên ngăn xếp, đảo ngược chúng, trừ và in sự khác biệt.


5

Hoàn toàn với sed (mặc dù hai lệnh với một đường ống)

sed '/ddd/,$!d' file | sed -n '$='

Xóa tất cả các dòng trước dòng và sau đó lệnh tiếp theo sẽ đếm các dòng trong tệp mới.


3

Điều này sẽ xóa tất cả các dòng lên đến (và bao gồm) một dòng có vấn đề và sau đó đếm các dòng còn lại:

sed '1,/problem/d' data.txt | wc -l

1
(giả sử "vấn đề" không nằm ở dòng đầu tiên)
Stéphane Chazelas
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.