ค้นหาข้อความทั่วทั้งระบบไฟล์ได้อย่างไร?


53

สมมติว่าควรใช้เครื่องมือ grep ฉันต้องการค้นหาสตริงข้อความ "800x600" ตลอดทั้งระบบไฟล์

ฉันเหนื่อย:

grep -r 800x600 /

แต่มันไม่ทำงาน

สิ่งที่ฉันเชื่อว่าคำสั่งของฉันควรทำคือ grep วนซ้ำผ่านไฟล์ / โฟลเดอร์ทั้งหมดภายใต้รูทสำหรับข้อความ "800x600" และแสดงรายการผลการค้นหา

ผมทำอะไรผิดหรือเปล่า?


2
และโดย "มันไม่ทำงาน" คุณหมายถึงอะไร มันไม่ได้พิมพ์ผลลัพธ์ใด ๆ แฮงค์หรือพิมพ์Permission deniedข้อผิดพลาดมากมายหรือไม่? คุณเรียกใช้เป็นรูทหรือผู้ใช้ปกติหรือไม่?
alex

ฉันได้รับแรงฉุดแรกของทั้งหมดที่ฉันอยู่ในไดเรกทอรีบ้านของผู้ใช้ของฉันพยายามเรียกใช้คำสั่ง ดังนั้นตอนนี้ฉันได้ cd / out เพื่อ root ต่อไปฉันลองคำสั่งเดียวกับข้างบนและฉันได้รับอนุญาตจำนวนมากปฏิเสธข้อผิดพลาด ตกลงดังนั้นตอนนี้ฉันลอง sudo grep -r 800x600 / และฉันได้รับ / proc / sysrq-trigger: ข้อผิดพลาดอินพุต / เอาต์พุต
Level1Coder

อืมไม่รู้ว่าทำไมมันไม่ทำงาน grep -r 800x600 / 2>/dev/nullคุณอาจจะละเว้นข้อผิดพลาดการเข้าถึงด้วยการทำ นอกจากนี้คุณยังสามารถลองเรียกใช้เป็นรูทได้
Totor

คำตอบ:


64

ปกติฉันจะใช้คำสั่งสไตล์นี้เพื่อรันgrepไฟล์จำนวนมาก:

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"

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

-xdevอาร์กิวเมนต์บอกพบว่ามันจะต้องละเว้น filesystems อื่น ๆ - นี้เป็นสิ่งที่ดีสำหรับการหลีกเลี่ยง filesystems /procพิเศษเช่น แต่ก็ยังจะไม่สนใจ filesystems ปกติเกินไป - ดังนั้นถ้ายกตัวอย่างเช่นโฟลเดอร์ของคุณ / บ้านเป็นในพาร์ทิชันที่แตกต่างกันก็จะไม่ได้รับการสืบค้น - find / /home -xdev ...คุณจะต้องบอกว่า

-type fหมายถึงค้นหาไฟล์เท่านั้นดังนั้นไดเรกทอรีอุปกรณ์และไฟล์พิเศษอื่น ๆ จะถูกละเว้น (มันจะยังคงเก็บในไดเรกทอรีและดำเนินการgrepกับไฟล์ภายใน - มันจะไม่ทำงานgrepในไดเรกทอรีเองซึ่งจะไม่ทำงาน) และ-Hตัวเลือกในการgrepบอกให้พิมพ์ชื่อไฟล์ในเอาต์พุตเสมอ

findยอมรับตัวเลือกทุกประเภทเพื่อกรองรายการไฟล์ ตัวอย่างเช่น-name '*.txt'ประมวลผลเฉพาะไฟล์ที่ลงท้ายด้วย. txt -size -2Mหมายถึงไฟล์ที่มีขนาดเล็กกว่า 2 เมกะไบต์ -mtime -5หมายถึงไฟล์ที่แก้ไขในช่วงห้าวันที่ผ่านมา เข้าร่วมเหล่านี้พร้อมกับ -a สำหรับและและ -o สำหรับหรือและใช้'('วงเล็บ')'ในการจัดกลุ่มนิพจน์ (ในเครื่องหมายคำพูดเพื่อป้องกันเชลล์จากการตีความพวกเขา) ตัวอย่างเช่น:

find / -xdev '(' -type f -a -name '*.txt' -a -size -2M -a -mtime -5 ')' -print0 | xargs -0 grep -H "800x600"

ลองman findดูรายการตัวกรองที่เป็นไปได้ทั้งหมด


2
โปรดทราบว่า-xdevจะยกเว้นระบบไฟล์อื่น ๆทั้งหมดไม่ใช่เฉพาะระบบไฟล์พิเศษ (เช่นหากคุณ/homeติดตั้งเป็นพาร์ติชันแยกต่างหากระบบจะไม่ทำการค้นหา)
cjm

ฉันพยายามเรียกใช้แต่ละรายการ แต่ทั้งคู่ส่งคืนข้อผิดพลาด -find: paths must precede expression: /
Level1Coder

1
หมายเหตุ: เมื่อไม่จำเป็นต้องใช้นิพจน์ทั่วไป 'fgrep' จะเร็วกว่า 'grep' อย่างมากซึ่งจะสร้างความแตกต่างอย่างมากหากคุณกำลังค้นหาต้นไม้ขนาดใหญ่
นาธาน Kidd

1
คุณสามารถหลีกเลี่ยงที่จะผ่านได้อย่างมีประสิทธิภาพอาจจะดีกว่าด้วยการทำxargs find / -xdev -type f -exec grep -H '800x600' +
Totor

3
ไม่+เครื่องหมายที่ท้ายfindคำสั่งจริง ๆ แล้วทำสิ่งเดียวกันกับxargs: มันวางไข่grepกระบวนการเดียวที่มีอาร์กิวเมนต์หลายอย่าง
Totor

14

โดยปกติแล้วคุณไม่ต้องการค้นหาทุกสิ่งบนระบบ Linux ใช้โหนดไฟล์สำหรับทุกสิ่งดังนั้น "ไฟล์" บางอย่างจึงไม่ใช่สิ่งที่คุณต้องการค้นหา ตัวอย่างเช่น/dev/sdaอุปกรณ์ฟิสิคัลบล็อกสำหรับฮาร์ดไดรฟ์แรกของคุณ คุณอาจต้องการค้นหาระบบไฟล์ที่เมาท์ไม่ใช่อุปกรณ์ดิสก์ดิบ นอกจากนี้ยังมี/dev/randomข้อมูลสุ่มที่คายออกมาทุกครั้งที่คุณอ่าน การค้นหาที่ไม่สมเหตุสมผล /procระบบไฟล์ยังเป็นปัญหาในกรณีของคุณ

ฉันขอแนะนำหนึ่งในสองสิ่งนี้

  1. อย่าค้นหาที่ root เพียงค้นหาสถานที่ที่อาจมีประโยชน์ ค้นหา/homeหรือ/usrหรือ/etcseparatly ข้อมูลที่คุณต้องการมีประเภทที่เฉพาะเจาะจงดังนั้นจึงมีแนวโน้มที่จะอยู่ในโฟลเดอร์เฉพาะ /etcการตั้งค่าที่ควรจะอยู่ใน /homeไฟล์ข้อมูลส่วนบุคคลของคุณควรจะอยู่ใน การ จำกัด การค้นหาในพื้นที่สำคัญเช่นนี้จะช่วยลดปัญหาของคุณกับ greps แบบเรียกซ้ำได้อย่างมาก

  2. ยกเว้นพื้นที่ที่มีปัญหา--exclude-dirและชุดของสิ่งที่คุณรู้ว่าคุณไม่ต้องการสิ่งนี้:
    grep -r --exclude-dir /proc --exclude-dir /dev --exclude-dir /tmp --exclude-dir /lost+found

สุดท้ายไม่ใช่เรื่องผิดปกติที่จะเรียกใช้ข้อผิดพลาด 'สิทธิ์ถูกปฏิเสธ' เมื่อทำการ grep ซ้ำที่มีขนาดใหญ่ ในการใช้งานตามปกติมีไฟล์ที่ผู้ใช้ของคุณอาจไม่สามารถอ่านได้ ตราบใดที่ไฟล์เหล่านี้เป็นเพียงไฟล์แปลก ๆ สองสามไฟล์และไม่ใช่สิ่งที่ต้องการอุปกรณ์ดิบสำหรับฮาร์ดไดรฟ์ของคุณหรือระบบไฟล์ proc ทั้งหมดคุณสามารถละเว้นข้อผิดพลาดได้ ในความเป็นจริงคุณสามารถทำได้ในบรรทัดคำสั่งโดยการส่งข้อผิดพลาดทั้งหมดไปที่ไม่เคยลงจอด:

grep -r search_string /path 2> /dev/null

3
-Iเพื่อแยกไบนารี่
Rahul Patil

2

สำหรับความเรียบง่ายที่ผมจะแนะนำACK-grep ลิงก์แสดงหลายกรณีเมื่อack-grepเป็นตัวเลือกที่ดีกว่า

วิธีใช้คือหลังจากติดตั้ง:

ack-grep pattern /

ขอบคุณที่แนะนำสิ่งนี้ แต่ฉันใช้งานมันและมันก็ไม่ได้ให้ผลลัพธ์การค้นหาที่ฉันคาดหวังไว้ ดูเหมือนว่าฉันจะต้องปรับแต่งการตั้งค่าต่าง ๆ เพื่อให้ได้สิ่งที่ฉันต้องการ ณ ตอนนี้คำตอบของริชาร์ดใช้ได้ทันทีที่ออกมาจากกล่อง จะมองเข้าไปในนี้ในอนาคตตามที่ดูเหมือนว่ามีประโยชน์เช่นกัน
Level1Coder


0

* จากนั้นฉันจะได้รับ / proc / sysrq-trigger: ข้อผิดพลาดอินพุต / เอาต์พุต

คำสั่งของคุณใช้งานได้คุณได้รับข้อผิดพลาดนี้เนื่องจากคุณพยายามสแกนกระบวนการที่กำลังทำงานเพื่อหาสตริง

ฉันขอแนะนำให้ยกเว้นไดเรกทอรีระบบด้วย

grep -exclude-dir = {proc, sys} "800x600" /


-3

เพียงขวา -

grep -r "800x600" /

- มีอะไรผิดปกติในคำสั่งปัจจุบันของคุณคือเครื่องหมายคำพูด "" ใส่อาร์กิวเมนต์สตริงไว้grepในเครื่องหมายคำพูดเสมอ


3
นี่ไม่ใช่ปัญหาที่นี่ grepคุณไม่จำเป็นต้องคำพูดเมื่อให้ประเภทนี้โดยเฉพาะของอาร์กิวเมนต์ ลองแล้วคุณจะเห็น ใส่สตริง "800x600" ลงในไฟล์จากนั้นgrep 800x600 fileคุณจะเห็นว่ามันใช้งานได้ดี เห็นได้ชัดว่า OP มีปัญหาอื่น ๆ
slm
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.