Tampilkan nama file sebelum baris yang cocok

282

Bagaimana saya bisa grepmenampilkan nama file sebelum baris yang cocok di outputnya?

Vivek
sumber
2
tolong beri tahu versi grep Andagrep --version
Kent
3
kent, grep --versionapakah perintah itu digunakan untuk mengetahui versi grep? Jika demikian, ini tidak berfungsi. Tidak dapat menemukan perintah lain untuk mengetahui versi grep.
Vivek
2
pertanyaan yang bagus tapi 'versi Os' adalah contoh nama file yang membingungkan
HaveAGuess
1
OS & versinya tidak relevan di sini.
MD XF
grep 'pattern' *
user0

Jawaban:

431

Coba trik kecil ini untuk membujuk grepagar berpikir itu berurusan dengan banyak file, sehingga ini menampilkan nama file:

grep 'pattern' file /dev/null

Untuk juga mendapatkan nomor baris:

grep -n 'pattern' file /dev/null
Pengamat
sumber
6
Ya itu berhasil. Bisakah Anda memberi tahu saya apa pentingnya menambahkan /dev/nullperintah ini?
Vivek
55
Jika grepdisediakan dengan beberapa nama file, itu akan secara otomatis menampilkan nama file sebelum pertandingan, tetapi itu akan meninggalkan nama file dalam kasus file input tunggal. Dengan menggunakan /dev/nullsebagai file input tambahan grep"berpikir" itu berurusan dengan banyak file, tetapi / dev / null tentu saja kosong, sehingga tidak akan muncul dalam daftar pertandingan ..
Scrutinizer
32
menggunakan / dev / null adalah trik yang cerdas, tapi saya pikir saran di bawah bendera -H adalah jawaban yang lebih baik.
JohnQ
22
OK, tetapi -Hopsi untuk grep bukan bagian dari POSIX, dan OS yang digunakan adalah Solaris 10, di mana baik grep standar, maupun versi grep yang sesuai dengan POSIX dari grep tidak memiliki -Hopsi.
Scrutinizer
4
Itu penting jika Anda menggunakan grep dengan find, seperti find . -name foo -exec grep pattern {} \;- dengan asumsi banyak file yang disebutkan foodalam subdirektori Anda, findmasih grepmemberikan satu file untuk beroperasi pada satu waktu. The /dev/nulltrick tampaknya bekerja di semua linux / OSX rasa yang saya sudah mencoba, jadi pujian! Catatan saya pikir itu -Hlebih bersih, tetapi seperti yang disebutkan di bawah, itu mungkin tidak didukung dengan versi Andagrep .
Jon V
297

Jika Anda memiliki opsi -Hdan -ntersedia ( man grepadalah teman Anda):

$ cat file
foo
bar
foobar

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

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

Pilihan:

-H, --dengan nama file

Cetak nama file untuk setiap kecocokan. Ini adalah default ketika ada lebih dari satu file untuk dicari.

-n, --line-number

Awali setiap baris output dengan nomor baris berbasis 1 di dalam file inputnya. (-n ditentukan oleh POSIX.)

-Hadalah ekstensi GNU, tetapi -nyang ditetapkan oleh POSIX

Chris Seymour
sumber
3
Tidak, -Htidak didukung di sini.
Vivek
1
Didukung tetapi selalu memberikan grep: file: Tidak ada file atau direktori seperti itu
pal4life
2
bekerja di ubuntu -H dan -n. Mungkin dengan semua versi * nix
tgkprog yang lebih baru
1
Saya telah berjuang dengan itu selama bertahun-tahun tanpa malam berpikir ada pilihan ini!
GreenSaguaro
46

Tidak perlu trik.

grep --with-filename 'pattern' file

Dengan nomor baris:

grep -n --with-filename 'pattern' file
MD XF
sumber
3
@ kodeforester Saya tidak tahu yang lain grep, jadi saya tidak tahu.
MD XF
2
Keren ! ini bekerja untuk linux. jika Anda menggunakan mac, dapat menginstal coreutils dengan minuman. Dan ingat, tambahkan PATH = "/ usr / local / opt / coreutils / libexec / gnubin: $ PATH" ke milik Anda .bashrc
zw963
2
Ini (juga) bekerja di MinGW (1.0.17, saya pikir).
Peter Mortensen
Ini berfungsi untuk saya dengan grep Mac bawaan (2.5.1-FreeBSD). Tetapi untuk menggunakan grep alternatif dari Homebrew, cara lain adalah menjalankan brew install grepdan kemudian hanya menggunakan ggrep. Tidak perlu memodifikasi PATH.
wonderlr
5

Bagaimana dengan ini, yang berhasil saya capai, sebagian, untuk posting ini.

Anda ingin menemukan beberapa file, misalkan log dengan nama yang berbeda tetapi sebuah pola (misalnya filename=logfile.DATE), di dalam beberapa direktori dengan pola (misalnya /logsapp1, /logsapp2). Setiap file memiliki pola yang Anda ingin grep (misalnya "init time"), dan Anda ingin memiliki "init time"masing-masing file, tetapi mengetahui file mana miliknya.

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

Maka outputfilename.txtakan menjadi sesuatu seperti

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

Secara umum

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

Penjelasan:

find perintah akan mencari nama file berdasarkan pada pola

kemudian, pipa xargs -I{}akan mengarahkan findoutput ke{}

yang akan menjadi input untuk grep ""pattern" {}

Kemudian trik untuk membuat greptampilan nama file\dev\null

dan akhirnya, tulis output dalam file dengan tee outputfile.txt

Ini bekerja untuk saya di grepversi 9.0.5 build 1989.

Lejuanjowski
sumber
3
Atau hanya menggunakan findfind ./path_pattern/to_files -type f -name "files*.log" -exec grep -Hn pattern {} \;
Martin
1

Ini sedikit modifikasi dari solusi sebelumnya. Contoh saya mencari pengarahan stderr dalam skrip bash: grep '2>' $(find . -name "*.bash")

Richard Jessop
sumber
-7
grep 'search this' *.txt

berhasil bagi saya untuk mencari melalui semua file .txt (masukkan nilai pencarian Anda sendiri, tentu saja).

MagicMojo
sumber