Hiển thị tên tệp trước khi khớp dòng


282

Làm cách nào tôi có grepthể hiển thị tên tệp trước các dòng khớp trong đầu ra của nó?


2
vui lòng cho biết phiên bản grep của bạngrep --version
Kent

3
Kent, grep --versionđó có phải là lệnh được sử dụng để biết phiên bản grep không? Nếu vậy, nó không hoạt động. Không thể tìm thấy bất kỳ lệnh nào khác để biết phiên bản grep.
Vivek

2
câu hỏi hay nhưng 'Phiên bản Os' là một tên tệp ví dụ khó hiểu
HaveAGuess

1
Hệ điều hành & phiên bản không liên quan ở đây.
MD XF

grep 'pattern' *
user0

Câu trả lời:


430

Hãy thử mẹo nhỏ này để dỗ grepnó nghĩ rằng nó đang xử lý nhiều tệp, để nó hiển thị tên tệp:

grep 'pattern' file /dev/null

Để có được số dòng:

grep -n 'pattern' file /dev/null

6
Vâng, nó đã làm việc. Bạn có thể vui lòng cho tôi biết tầm quan trọng của việc thêm /dev/nullvào lệnh này không?
Vivek

55
Nếu grepđược cung cấp nhiều tên tệp, nó sẽ tự động hiển thị tên tệp trước khi khớp, nhưng nó sẽ để lại tên tệp trong trường hợp một tệp đầu vào. Bằng cách sử dụng /dev/nullnhư một tệp đầu vào bổ sung grep"nghĩ" nó xử lý nhiều tệp, nhưng / dev / null tất nhiên là trống, vì vậy nó sẽ không hiển thị trong danh sách khớp ..
Scrutinizer 18/03/13

32
sử dụng / dev / null là một mẹo thông minh, nhưng tôi nghĩ gợi ý bên dưới của cờ -H là một câu trả lời tốt hơn.
JohnQ

22
OK, nhưng -Htùy chọn cho grep không phải là một phần của POSIX và HĐH được sử dụng là Solaris 10, trong đó cả grep tiêu chuẩn, cũng không phải là phiên bản grep tuân thủ POSIX -H.
Scrutinizer

4
Điều đó rất quan trọng nếu bạn đang sử dụng grep với find, như find . -name foo -exec grep pattern {} \;- giả sử có nhiều tệp có tên footrong thư mục con của bạn, findvẫn đưa grepmột tệp duy nhất để hoạt động cùng một lúc. Thủ /dev/nullthuật dường như hoạt động trong tất cả các hương vị linux / osx mà tôi đã thử, vì vậy, kudos! Lưu ý tôi nghĩ rằng -Hlà sạch, nhưng như đã đề cập dưới đây, nó có thể không được hỗ trợ với bạn phiên bản của grep.
Jon V

296

Nếu bạn có các tùy chọn -H-ncó sẵn ( man greplà bạn của bạn):

$ cat file
foo
bar
foobar

$ grep -H foo file
file:foo
file:foobar

$ grep -Hn foo file
file:1:foo
file:3:foobar

Tùy chọn:

-H, - với tên tệp

In tên tập tin cho mỗi trận đấu. Đây là mặc định khi có nhiều hơn một tệp để tìm kiếm.

-n, - số dòng

Tiền tố mỗi dòng đầu ra với số dòng dựa trên 1 trong tệp đầu vào của nó. (-n được chỉ định bởi POSIX.)

-Hlà một phần mở rộng GNU, nhưng -nđược chỉ định bởi POSIX


3
Không, -Hkhông được hỗ trợ ở đây.
Vivek

1
Được hỗ trợ nhưng nó luôn cung cấp cho grep: file: Không có tệp hoặc thư mục như vậy
pal4life

2
hoạt động trên Ubuntu -H và -n. Có lẽ với tất cả các phiên bản mới hơn của * nix
tgkprog

1
Tôi đã vật lộn với điều đó trong nhiều năm mà không nghĩ rằng có những lựa chọn này!
GreenSaguaro

45

Không có mẹo cần thiết.

grep --with-filename 'pattern' file

Với số dòng:

grep -n --with-filename 'pattern' file

3
@codeforester Tôi không biết bất kỳ greps nào khác , vì vậy tôi không biết.
MD XF

2
Mát mẻ ! Điều này làm việc cho linux. Nếu bạn sử dụng mac, có thể cài đặt coreutils với brew. Và nhớ thêm PATH = "/ usr / local / opt / coreutils / libexec / gnubin: $ PATH" vào của bạn .bashrc
zw963

2
Điều này (cũng) đã làm việc trong MinGW (1.0.17, tôi nghĩ).
Peter Mortensen

Nó hoạt động với tôi với Mac grep tích hợp (2.5.1-FreeBSD). Nhưng để sử dụng grep thay thế từ Homebrew, một cách khác là chạy brew install grepvà sau đó chỉ cần sử dụng ggrep. Không cần phải sửa đổi PATH.
wonderlr

5

Làm thế nào về điều này, mà tôi quản lý để đạt được cảm ơn, một phần, cho bài viết này.

Bạn muốn tìm một số tệp, giả sử nhật ký với các tên khác nhau nhưng một mẫu (ví dụ filename=logfile.DATE), bên trong một số thư mục có mẫu (ví dụ /logsapp1, /logsapp2). Mỗi tệp có một mẫu bạn muốn grep (ví dụ "init time") và bạn muốn có "init time"từng tệp, nhưng biết tệp đó thuộc về tệp nào.

find ./logsapp* -name logfile* | xargs -I{} grep "init time" {} \dev\null | tee outputfilename.txt

Sau đó, outputfilename.txtsẽ là một cái gì đó như

./logsapp1/logfile.22102015: init time: 10ms
./logsapp1/logfile.21102015: init time: 15ms
./logsapp2/logfile.21102015: init time: 17ms
./logsapp2/logfile.22102015: init time: 11ms

Nói chung

find ./path_pattern/to_files* -name filename_pattern* | xargs -I{} grep "grep_pattern" {} \dev\null | tee outfilename.txt

Giải trình:

find lệnh sẽ tìm kiếm tên tệp dựa trên mẫu

sau đó, ống xargs -I{}sẽ chuyển hướng findđầu ra đến{}

đó sẽ là đầu vào cho grep ""pattern" {}

Sau đó, mẹo để grephiển thị tên tệp\dev\null

và cuối cùng, viết đầu ra trong tệp với tee outputfile.txt

Điều này làm việc cho tôi trong grepphiên bản 9.0.5 build 1989.


3
Hoặc chỉ sử dụng findfind ./path_pattern/to_files -type f -name "files*.log" -exec grep -Hn pattern {} \;
Martin

1

Đây là một sửa đổi nhỏ từ một giải pháp trước đó. Ví dụ của tôi tìm kiếm chuyển hướng stderr trong các tập lệnh bash: grep '2>' $(find . -name "*.bash")


-7
grep 'search this' *.txt

làm việc cho tôi để tìm kiếm thông qua tất cả các tệp .txt (tất nhiên, nhập giá trị tìm kiếm của riêng bạn).

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.