Grep ไม่ใช่นิพจน์ทั่วไป


96

$someVarฉันจำเป็นต้องค้นหาตัวแปร PHP อย่างไรก็ตาม Grep คิดว่าฉันพยายามเรียกใช้ regex และบ่นว่า:

$ grep -ir "Something Here" * | grep $someVar
Usage: grep [OPTION]... PATTERN [FILE]...
Try `grep --help' for more information.
$ grep -ir "Something Here" * | grep "$someVar"
<<Here it returns all rows with "someVar", not only those with "$someVar">>

ฉันไม่เห็นตัวเลือกในการบอก grep ว่าอย่าตีความสตริงเป็น regex แต่รวม$อักขระสตริงอื่นไว้ด้วย


3
ในคำถามนี้ประเด็นหลักไม่ใช่เรื่องgrepการตีความ$เป็นนิพจน์ทั่วไป มันเกี่ยวกับการแทนที่เชลล์$someVarด้วยค่าของตัวแปรสภาพแวดล้อมsomeVarซึ่งน่าจะเป็นสตริงว่าง ตัวอย่างที่สองไม่ควรส่งคืนแถวทั้งหมดที่มีsomeVarแต่บรรทัดทั้งหมดเนื่องจากสตริงว่างอยู่ในทุกบรรทัด ที่จะบอกเปลือกจะไม่ได้ใช้แทนคุณต้องใช้หรือ'$someVar' \$someVarจากนั้นคุณจะต้องจัดการกับการgrepตีความ$ตัวละคร
Christophe Drevet-Droguet

1
@ ChristopheDrevet-Droguet: ขอบคุณสำหรับคำอธิบายฉันงงงวยกับการโหวตลด! ความคิดเห็นของคุณเป็นข้อมูลที่เพียงพอที่จะเป็นคำตอบ แต่ถ้าเป็นเช่นนั้นมันจะเป็นคำตอบที่ดีกว่า
dotancohen

คำตอบ:



299

ใช้fgrep(เลิกใช้งานแล้ว) grep -Fหรือgrep --fixed-stringsเพื่อให้รูปแบบเป็นรายการสตริงคงที่แทนนิพจน์ทั่วไป

สำหรับการอ้างอิงเอกสารกล่าวถึง (ข้อความที่ตัดตอนมา):

-F --fixed-stringsตีความรูปแบบเป็นรายการของสตริงคงที่ (แทนที่จะเป็นนิพจน์ทั่วไป) คั่นด้วยขึ้นบรรทัดใหม่ซึ่งจะจับคู่แบบใดก็ได้ (-F ระบุโดย POSIX)

fgrepเหมือนกับgrep -F. การเรียกใช้โดยตรงเนื่องจาก fgrep เลิกใช้งานแล้ว แต่มีไว้เพื่ออนุญาตให้แอปพลิเคชันในอดีตที่ต้องอาศัยแอปพลิเคชันทำงานโดยไม่ได้แก้ไข

ดูข้อมูลอ้างอิงทั้งหมดได้ที่ https://www.gnu.org/savannah-checkouts/gnu/grep/manual/grep.html


คำตอบที่ดีง่ายๆ
breadmj

ตกลง - เมื่อคุณใช้ตัวแปรคุณไม่สามารถทำบางอย่างเช่น PHP addslashes()กับมันใน bash นี่เป็นวิธีที่ง่ายที่สุดที่จะทำได้
geerlingguy

1
ขอบคุณสิ่งนี้ได้ผล คำเตือน: หากใช้เครื่องหมายคำพูดคู่คุณจะต้องหลีกเลี่ยง$เช่น: grep -FR "unset(\$foo['bar'])"มิฉะนั้นจะคิดว่าเป็นตัวแปรภายนอกและพยายามขยาย
aexl

57

grep -Fเป็นวิธีมาตรฐานในการบอกgrepให้ตีความอาร์กิวเมนต์เป็นสตริงคงที่ไม่ใช่รูปแบบ


1
อย่างจริงจังนี่ควรเป็นคำตอบที่ได้รับการยอมรับ!
ankush981

คำตอบที่ดี มันแก้ไขปัญหาของฉันเมื่อฉันค้นหาสตริงด้วย $ โดยใช้คำสั่ง ssh การหนีด้วย "\" ไม่ได้ผลในสถานการณ์นั้น แต่แฟล็ก -F ทำเคล็ดลับ
Rajasekhar


3

ในคำถามนี้ประเด็นหลักไม่ใช่เรื่องgrepการตีความ$เป็นนิพจน์ทั่วไป มันเกี่ยวกับการแทนที่เชลล์$someVarด้วยค่าของตัวแปรสภาพแวดล้อมsomeVarซึ่งน่าจะเป็นสตริงว่าง

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

ที่จะบอกเปลือกจะไม่ได้ใช้แทนคุณต้องใช้หรือ'$someVar' \$someVarจากนั้นคุณจะต้องจัดการกับการตีความ grep ของ$ตัวละครดังนั้นgrep -Fตัวเลือกที่ให้ไว้ในคำตอบอื่น ๆ

ดังนั้นหนึ่งคำตอบที่ถูกต้องคือ:

grep -ir "Something Here" * | grep '$someVar'

2

+1 สำหรับ-Fตัวเลือกนั้นจะเป็นคำตอบที่ยอมรับ นอกจากนี้ฉันยังมีพฤติกรรม "แปลก ๆ " ขณะค้นหา-I..รูปแบบในไฟล์ของฉันเนื่องจาก-Iถือว่าเป็นตัวเลือกของgrep; --เพื่อหลีกเลี่ยงเช่นชนิดของข้อผิดพลาดของเราอย่างชัดเจนสามารถระบุในตอนท้ายของการขัดแย้งของคำสั่งโดยใช้

ตัวอย่าง:

grep -HnrF -- <pattern> <files>

หวังว่าจะช่วยใครสักคน


F ย่อมาจากอะไร?
Arnold Roa

จากgnu.org/software/grep/manual/grep.html : "-F: ตีความรูปแบบเป็นรายการสตริงคงที่ (แทนที่จะเป็นนิพจน์ทั่วไป) คั่นด้วยขึ้นบรรทัดใหม่ซึ่งจะจับคู่แบบใดก็ได้ (-F ระบุโดย POSIX) "
Aloïké Go

ถ้า--ใช้-HnrFจะเว้นได้ไหม?
Daniel

@ แดเนียลขึ้นอยู่กับสิ่งที่คุณต้องการทำ: -Fหลีกเลี่ยงการตีความรูปแบบเป็นนิพจน์ทั่วไปในขณะที่--หลีกเลี่ยงการตีความองค์ประกอบที่ตามมาเป็นตัวเลือกของ grep
Aloïké Go

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