แสดงชื่อไฟล์ก่อนการจับคู่บรรทัด


282

ฉันgrepจะแสดงชื่อไฟล์ต่อหน้าบรรทัดที่ตรงกันในเอาต์พุตได้อย่างไร


2
กรุณาบอก grep เวอร์ชั่นของคุณgrep --version
Kent

3
kent grep --versionนั่นคือคำสั่งที่จะใช้ในการรู้เวอร์ชัน grep หรือไม่? ถ้าเป็นเช่นนั้นมันไม่ทำงาน ไม่พบคำสั่งอื่นใดที่จะทราบรุ่น grep
Vivek

2
คำถามที่ดี แต่ 'รุ่น Os' เป็นชื่อไฟล์ตัวอย่างที่สับสน
HaveAGuess

1
ระบบปฏิบัติการและเวอร์ชั่นไม่เกี่ยวข้องที่นี่
MD XF

grep 'pattern' *
0

คำตอบ:


430

ลองเคล็ดลับเล็ก ๆ นี้เพื่อเกลี้ยกล่อมgrepให้คิดว่ามันกำลังจัดการกับไฟล์หลายไฟล์เพื่อที่จะแสดงชื่อไฟล์:

grep 'pattern' file /dev/null

วิธีรับหมายเลขบรรทัดด้วย:

grep -n 'pattern' file /dev/null

6
ใช่มันใช้งานได้ คุณช่วยกรุณาบอกฉันว่าอะไรคือความสำคัญของการเพิ่ม/dev/nullในคำสั่งนี้?
Vivek

55
หากgrepมีชื่อไฟล์หลายชื่อจะแสดงชื่อไฟล์โดยอัตโนมัติก่อนการแข่งขัน แต่จะปล่อยชื่อไฟล์ออกในกรณีที่มีไฟล์อินพุตไฟล์เดียว โดยการใช้/dev/nullเป็นไฟล์อินพุตพิเศษgrep"คิดว่า" มันจัดการกับไฟล์หลายไฟล์ แต่ / dev / null ว่างเปล่าแน่นอนดังนั้นมันจะไม่ปรากฏในรายการที่ตรงกัน ..
Scrutinizer

32
การใช้ / dev / null เป็นเคล็ดลับที่ฉลาด แต่ฉันคิดว่าคำแนะนำด้านล่างของแฟล็ก -H เป็นคำตอบที่ดีกว่า
JohnQ

22
ตกลง แต่-Hตัวเลือกสำหรับ grep ไม่ได้เป็นส่วนหนึ่งของ POSIX และระบบปฏิบัติการที่ใช้คือ Solaris 10 โดยที่ grep มาตรฐานหรือ POSIX เวอร์ชันที่สอดคล้องกับ grep ไม่มี-Hตัวเลือก
Scrutinizer

4
ที่สำคัญถ้าคุณกำลังใช้ grep ด้วยหาเช่นfind . -name foo -exec grep pattern {} \;- สมมติความอุดมสมบูรณ์ของชื่อไฟล์fooในไดเรกทอรีย่อยของคุณfindยังคงมือgrepไฟล์เดียวที่จะดำเนินการในช่วงเวลาที่ /dev/nullเคล็ดลับดูเหมือนว่าจะทำงานในลินุกซ์ / OSX รสชาติทุกสิ่งที่ฉันได้พยายามเพื่อความรุ่งโรจน์! หมายเหตุ: ผมคิดว่า-Hสะอาด แต่ดังกล่าวข้างล่างก็อาจจะไม่ได้รับการสนับสนุนกับคุณgrepรุ่นของ
Jon V

296

หากคุณมีตัวเลือก-Hและ-nพร้อมใช้งาน ( man grepเป็นเพื่อนของคุณ):

$ cat file
foo
bar
foobar

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

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

ตัวเลือก:

-H, - ด้วยชื่อไฟล์

พิมพ์ชื่อไฟล์สำหรับการแข่งขันแต่ละครั้ง นี่คือค่าเริ่มต้นเมื่อมีมากกว่าหนึ่งไฟล์ที่จะค้นหา

-n, - หมายเลขบรรทัด

ใส่คำนำหน้าแต่ละบรรทัดของเอาต์พุตด้วยหมายเลขบรรทัดที่อ้างอิง 1 ภายในไฟล์อินพุต (-n ถูกระบุโดย POSIX)

-Hเป็นนามสกุล GNU แต่-nถูกระบุโดย POSIX


3
ไม่-Hไม่รองรับที่นี่
Vivek

1
ได้รับการสนับสนุน แต่จะให้ grep: file: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว
pal4life

2
ทำงานบน ubuntu -H และ -n อาจเป็นกับ * nix รุ่นใหม่ทั้งหมด
tgkprog

1
ฉันต่อสู้กับมันมาหลายปีโดยไม่คิดว่าจะมีทางเลือกเหล่านี้!
GreenSaguaro

45

เคล็ดลับไม่จำเป็น

grep --with-filename 'pattern' file

ด้วยหมายเลขบรรทัด:

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

3
@ codeforester ฉันไม่รู้ของคนอื่นgrepดังนั้นฉันไม่รู้
MD XF

2
เจ๋ง! สิ่งนี้ใช้ได้กับ linux ถ้าคุณใช้ mac สามารถติดตั้ง coreutils ด้วยการชง และอย่าลืมเพิ่ม PATH = "/ usr / local / opt / coreutils / libexec / gnubin: $ PATH" ให้กับคุณ. bashrc
zw963

2
(เช่น) ทำงานในMinGW (1.0.17 ฉันคิดว่า)
Peter Mortensen

มันทำงานได้ดีสำหรับฉันกับ grep Mac ในตัว (2.5.1-FreeBSD) แต่การที่จะใช้ grep ทางเลือกจาก Homebrew, อีกวิธีหนึ่งคือการทำงานและจากนั้นเพียงแค่ใช้brew install grep ggrepไม่จำเป็นต้องแก้ไข PATH
wonderlr

5

วิธีการเกี่ยวกับเรื่องนี้ซึ่งฉันจัดการเพื่อให้ได้มาซึ่งส่วนหนึ่งของโพสต์นี้

คุณต้องการค้นหาไฟล์หลาย ๆ ไฟล์สมมติว่าบันทึกที่มีชื่อแตกต่างกัน แต่มีรูปแบบ (เช่นfilename=logfile.DATE) ภายในหลาย ๆ ไดเรกทอรีที่มีรูปแบบ (เช่น/logsapp1, /logsapp2) แต่ละไฟล์มีรูปแบบที่คุณต้องการ grep (เช่น"init time") และคุณต้องการที่จะมี"init time"ของแต่ละไฟล์ แต่รู้ว่ามันเป็นไฟล์ใด

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

จากนั้นoutputfilename.txtจะเป็นสิ่งที่ชอบ

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

โดยทั่วไปแล้ว

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

คำอธิบาย:

find คำสั่งจะค้นหาชื่อไฟล์ตามรูปแบบ

จากนั้นไพพ์xargs -I{}จะเปลี่ยนทิศทางfindเอาต์พุตไปที่{}

ซึ่งจะเป็นอินพุตสำหรับ grep ""pattern" {}

จากนั้นเคล็ดลับที่จะทำให้การgrepแสดงชื่อไฟล์\dev\null

และสุดท้ายเขียนผลลัพธ์ในไฟล์ด้วย tee outputfile.txt

สิ่งนี้ใช้ได้กับฉันในgrepเวอร์ชัน 9.0.5 build 1989


3
หรือเพียงแค่ใช้ findfind ./path_pattern/to_files -type f -name "files*.log" -exec grep -Hn pattern {} \;
Martin

1

นี่เป็นการแก้ไขเล็กน้อยจากโซลูชันก่อนหน้า ตัวอย่างของฉันค้นหาการเปลี่ยนเส้นทาง stderr ในสคริปต์ทุบตี: grep '2>' $(find . -name "*.bash")


-7
grep 'search this' *.txt

ทำงานให้ฉันค้นหาไฟล์. txt ทั้งหมด (ป้อนค่าการค้นหาของคุณเอง)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.