ฉันจะค้นหาไฟล์ทั้งหมดที่ไม่มีสตริงข้อความได้อย่างไร?


40

ฉันสามารถใช้คำสั่งรวบรัดอะไรเพื่อค้นหาไฟล์ทั้งหมดที่ไม่มีสตริงข้อความ?

ฉันลองสิ่งนี้ (โดยใช้ -v เพื่อสลับพารามิเตอร์ของ grep) โดยไม่มีโชค:

find . -exec grep -v -l shared.php {} \;

มีคนกล่าวว่าสิ่งนี้จะได้ผล:

find . ! -exec grep -l shared.php {} \;

แต่ดูเหมือนจะไม่ได้ผลสำหรับฉัน

หน้านี้มีตัวอย่างนี้:

find ./logs -size +1c  > t._tmp
while read filename
do
     grep -q "Process Complete" $filename
     if [ $? -ne 0 ] ; then
             echo $filename
     fi
done < t._tmp
rm -f t_tmp

แต่มันยุ่งยากและไม่รัดกุมเลย

ป.ล. : ฉันรู้ว่าgrep -L *จะทำเช่นนี้ แต่ฉันจะใช้คำสั่ง find ร่วมกับ grep เพื่อยกเว้นไฟล์ได้อย่างไรคือสิ่งที่ฉันอยากรู้

pss: ยังฉันไม่แน่ใจว่าจะมี grep รวมไดเรกทอรีย่อยที่มีgrep -L *ไวยากรณ์ แต่ฉันยังต้องการทราบวิธีการใช้กับfind:)


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

@rahmu คำสั่งนี้แทบจะไม่ทำงานตามที่คุณคาดหวัง คุณอาจมีกรณีที่เฉพาะเจาะจงมาก โปรดดูunix.stackexchange.com/questions/339619/…
sgnsajgon

คำตอบ:


8
find . -type f | xargs grep -H -c 'shared.php' | grep 0$ | cut -d':' -f1    

หรือ

find . -type f -exec grep -H -c 'shared.php' {} \; | grep 0$ | cut -d':' -f1

ที่นี่เรากำลังคำนวณจำนวนบรรทัดที่ตรงกัน (โดยใช้-c) ในไฟล์ถ้าจำนวนเป็น 0 ดังนั้นไฟล์ที่ต้องการดังนั้นเราจึงตัดคอลัมน์แรกเช่นชื่อไฟล์จากเอาต์พุต


6
มันซับซ้อนมาก ดูคำตอบของเควิน
Gilles 'หยุดความชั่วร้าย'

@Gilles ใช่ฉันเห็นด้วยกับคุณ ฉันมี +1 คำตอบของเขา
Sachin Divekar

6
สิ่งนี้ไม่เพียง "ซับซ้อนอย่างยิ่งยวด" แต่ผิดเพราะมันจะแสดงรายการไฟล์ทั้งหมดที่มีหลายบรรทัด 10 บรรทัดที่ตรงกับรูปแบบ แม้ว่าจะgrepได้รับการแก้ไข แต่ก็ยังคงไม่มีชื่อไฟล์ที่มี:หรืออักขระขึ้นบรรทัดใหม่ ...
don_crissti

@don_crissti ขอบคุณที่กล่าวถึง! ยังคงเว้นแต่ว่าคุณจะใช้รหัสคัดลอกวางจำนวนมากการแก้ปัญหาข้างต้นเป็นกลไกที่ดี
Ufos

@Ufos - ผมไม่ได้รับความคิดเห็นของคุณ ... นี้เป็นที่ไม่ถูกต้อง อย่างไรก็ตามรู้สึกอิสระที่จะใช้มันหากดูเหมือนว่า "กลไกที่ดีจริงๆ" กับคุณ ...
don_crissti

56

การค้นหาของคุณควรใช้งานได้หากคุณเปลี่ยน-v -l(ไฟล์ที่มีบรรทัดที่ไม่ตรงกัน) เป็น-L(ไฟล์ที่ไม่มีการจับคู่บรรทัด) แต่คุณสามารถใช้ตัวเลือกgreprecursive ( -r) ของ:

grep -rL shared.php .

ซึ่งการค้นหาควรทำงานอย่างไร
cwd

@ เควิน - ขอโทษfind . -exec grep -v -l shared.php {} \;(และตัวแปรอื่น ๆ ทั้งหมดที่ฉันพยายาม) ไม่ทำงานสำหรับฉัน ฉันใช้ OS X แต่ฉันไม่คิดว่ามันจะสำคัญ ฉันให้ +1 เพราะคุณลืมตัว-rเลือก
cwd

@cwd ฉันรู้ว่านี่เก่า แต่ฉันต้องการออกจากที่นี่เพื่อผู้อ่านในอนาคต: ความจริงที่ว่าคุณอยู่บน OS X สร้างความแตกต่าง Mac OSX ใช้คำสั่ง FreeBSD คนส่วนใหญ่ที่นี่ถือว่าคำสั่งสไตล์ Linux (GNU) พวกเขามีข้อโต้แย้งต่างกันวิธีการจัดการรายละเอียดต่าง ๆ
Rich Homolka

ตั้งแต่ปี 2016 OSX ไม่ได้รับการสนับสนุน-L
David Moles

@ เควินฉันบอกว่ามันทำไม่ได้ไม่ใช่ :) ไม่ใช่ที่ทุกคนพูดอย่างชัดเจนว่ามันไม่ได้ แต่ความคิดเห็นนั้นสับสน (และฉันได้พบปัญหาอื่น ๆ ของ OS X / BSD vs GNU)
David Moles

4

ฉันรู้ว่าgrep -L *จะทำเช่นนี้ แต่ฉันจะใช้findคำสั่งร่วมกับgrepการยกเว้นไฟล์ได้อย่างไรคือสิ่งที่ฉันอยากรู้

คุณสามารถใช้findและgrepชอบสิ่งนี้:

find . -type f ! -exec grep -q 'PATTERN' {} \; -print

ที่นี่-printจะถูกดำเนินการเฉพาะในกรณีที่การแสดงออกก่อนหน้านี้: ประเมินเป็น! -exec ... {} ดังนั้นสำหรับแต่ละไฟล์ที่พบจะถูกใช้ถ้าผลลัพธ์เป็นเช่นนั้นนิพจน์ทั้งหมดจะประเมินว่าและชื่อไฟล์นั้นถูกเอ็ดtrue
grep -q 'PATTERN'execfalse! -exec grep -q 'PATTERN'trueprint


2
สิ่งนั้นมีประโยชน์ในการเป็นมาตรฐานและพกพาได้
Stéphane Chazelas

มีความแตกต่างกับ GNU grep -Lถึงแม้ว่ามันจะรวมไฟล์ที่ไม่สามารถอ่านได้ในรายการด้วย
Stéphane Chazelas


-1

ฉันคิดว่าคุณกำลังมองหาคำสั่งเช่น

find . -type f -execdir grep -q -v shared.php {} \; -print

ตัวเลือกนี้-qทำให้grepเลิกและหลังจากใช้งาน-execdirคุณต้อง-printพิมพ์ไฟล์ที่พบ


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