Sử dụng grep để chỉ báo cáo lại số dòng


105

Tôi có một tệp có thể chứa định dạng không hợp lệ (trong trường hợp này là sự xuất hiện của mẫu \\backslash). Tôi chỉ muốn sử dụng grepđể trả về số dòng nơi điều này xảy ra (như trong, kết quả khớp ở đây, hãy chuyển đến dòng # x và sửa nó).

Tuy nhiên, dường như không có cách nào để in số dòng ( grep -n) và không phải khớp hoặc chính dòng.

Tôi có thể sử dụng một regex khác để trích xuất số dòng, nhưng tôi muốn đảm bảo rằng grep không thể tự làm điều đó. grep -nođến gần nhất, tôi nghĩ, nhưng vẫn hiển thị trận đấu.


1
Câu trả lời hữu ích nhất cho tôi là trong câu hỏi grep -no:! Điều này đã làm những gì tôi đến đây để thử và làm! (tức là không in dòng đôi khi rất dài, ví dụ: các tệp nguồn javascript được
rút gọn

Câu trả lời:


155

thử:

grep -n "text to find" file.ext | cut -f1 -d:

1
Trên máy tính của tôi, điều này chỉ được in các tập tin phù hợp mà không cần số dòng (vì vậy nếu tôi có 3 trận đấu bên trong một tập tin nó chỉ được in một lần) mà là rất hữu ích vẫn ...
Mario Awad

3
@MarioAwad, bạn nên thao tác với -fparam. Đối với tôi đó là -f2. (Biết đây là những thứ cũ, nhưng tôi nghĩ rằng nó có thể giúp một số linh hồn nghèo)
Emil Sierżęga

cảm ơn vì kịch bản shell adhoc unix cũ đáng yêu. điều này cho thấy rằng các công cụ linh hoạt xứng đáng với độ phức tạp và đường cong học tập của chúng!
Alex

12
grep -n "text to find" file.ext | cut -f1,2 -d:hiển thị tên tệp và số dòng.
Jondlm

2
@jondim nó chỉ hiển thị tên tệp nếu có nhiều hơn một tệp đang được tìm kiếm; bạn cần thêm -Hđể buộc nó hiển thị tên tệp khi chỉ có một tệp. Ngược lại, bạn luôn có thể sử dụng -hđể yêu cầu nó không xuất ra tên tệp bất kể bạn đang gửi bao nhiêu tệp.
Mark Reed

45

Nếu bạn muốn sử dụng AWK:

awk '/textstring/ {print FNR}' textfile

Trong trường hợp này, FNR là số dòng. AWK là một công cụ tuyệt vời khi bạn đang xem xét grep | cut hoặc bất kỳ lúc nào bạn đang tìm cách lấy đầu ra grep và thao tác với nó.


2
Sử dụng một quy trình (trước đây quan trọng hơn nhưng vẫn còn) và đủ dễ hiểu cho người mới bắt đầu awk!
bgStack

NRhoạt động tốt khi chỉ có một tệp được kiểm tra, như trong trường hợp này.
Mark Reed

Đơn giản rực rỡ! Nó quá nhanh!
GTodorov

34

Tất cả các câu trả lời này yêu cầu grep để tạo toàn bộ các dòng phù hợp, sau đó chuyển nó sang một chương trình khác. Nếu các dòng của bạn rất dài, có thể hiệu quả hơn nếu chỉ sử dụng sed để xuất số dòng:

sed -n '/pattern/=' filename

2

Phiên bản bash

    lineno=$(grep -n "pattern" filename)
    lineno=${lineno%%:*}

1
Và điều gì sẽ xảy ra nếu nhiều hơn một dòng khớp với mẫu đó?
izabera

@izabera thêm | tail -1
Diego

1

Tôi đề xuất các câu trả lời có sedawkchỉ lấy số dòng, thay vì sử dụng grepđể lấy toàn bộ dòng phù hợp và sau đó xóa nó khỏi đầu ra bằng cuthoặc công cụ khác. Để hoàn thiện, bạn cũng có thể sử dụng Perl:

perl -nE '/pattern/ && say $.' filename

hoặc Ruby:

ruby -ne 'puts $. if /pattern/' filename

0

Bạn sẽ muốn trường thứ hai sau dấu hai chấm, không phải trường đầu tiên.

grep -n "text to find" file.txt | cut -f2 -d:


Điều này hoạt động nếu bạn muốn khớp văn bản, nhưng trong trường hợp số dòng là những gì OP yêu cầu.
AJP

0

Để đếm số dòng phù hợp với mẫu:

grep -n "Pattern" in_file.ext | wc -l 

Để trích xuất mẫu phù hợp

sed -n '/pattern/p' file.est

Để hiển thị số dòng trên mẫu nào đã khớp

grep -n "pattern" file.ext | cut -f1 -d:

2
Đầu tiên chỉ nên là "grep -c 'Pattern' in_file.ext". Thứ 2 phải là "grep -o 'Pattern' in_file.ext". Không cần liên quan đến sed hoặc wc.
thelogix

0

chỉ sử dụng grep :

grep -n "text to find" file.ext | grep -Po '^[^:]+'

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.