เมื่อใดที่จะใช้เครื่องหมายคำพูดเดี่ยวอัญประกาศเป็น grep


20

ในขณะที่พยายามค้นหารูปแบบง่าย ๆ "สวัสดี" ในไฟล์รูปแบบของ grep ต่อไปนี้ทั้งหมดทำงาน:

  • grep สวัสดี file1
  • grep 'hello' file1
  • grep "hello" file1

มีกรณีเฉพาะที่หนึ่งในรูปแบบข้างต้นทำงานได้ แต่คนอื่นไม่ มันสร้างความแตกต่างหรือไม่ถ้าฉันใช้อันอื่น?

คำตอบ:


25

สิ่งนี้ขึ้นอยู่กับเปลือกของคุณ คำพูด (ทั้งสองประเภท) มีวัตถุประสงค์เพื่อจัดการกับช่องว่างเป็นหลัก ตัวอย่างเช่นต่อไปนี้:

grep hello world file1

จะมองหาคำว่า "สวัสดี" ในไฟล์ที่เรียกว่า "โลก" และ "file1" ในขณะที่

grep "hello world" file1

จะมองหา "hello world" ใน file1

ตัวเลือกระหว่างเครื่องหมายคำพูดเดี่ยวหรือคู่มีความสำคัญเฉพาะถ้าสตริงการค้นหามีตัวแปรหรือรายการอื่น ๆ ที่คุณคาดว่าจะได้รับการประเมิน ด้วยเครื่องหมายคำพูดเดี่ยวสตริงจะถูกใช้อย่างแท้จริงและไม่มีการขยายเกิดขึ้น ด้วยเครื่องหมายคำพูดคู่ตัวแปรจะถูกขยาย ตัวอย่างเช่น (ด้วยเชลล์ที่ได้รับจาก Bourne เช่น Bash หรือ ZSH):

VAR="serverfault"
grep '$VAR' file1
grep "$VAR" file1

สิ่งแรกgrepจะค้นหาสตริงตัวอักษร "$ VAR1" ใน file1 ที่สองจะขยายตัวแปร "$ VAR" และค้นหาสตริง "serverfault" ใน file1


สิ่งสำคัญที่ควรทราบคือในคำถามเดิม grep ได้รับข้อโต้แย้งเดียวกันทุกครั้ง
MikeyB

2
ระวังให้ดี $เป็นจุดสิ้นสุดของบรรทัดในนิพจน์ทั่วไปดังนั้น$VAR1ไม่ควรจับคู่กับสิ่งใดเลย มันเกิดขึ้นกับการทำงานกับ GNU grep แต่ฉันก็ยังไม่เชื่อในพฤติกรรมนั้น คุณจะต้อง\$VAR1จับคู่สตริงตัวอักษรให้ปลอดภัย (และคุณจะต้อง backslashes พิเศษถ้าที่อยู่ในคำพูดสอง.)
สตีเว่น Pritchard

7

James ถูกต้อง แต่เพื่อเพิ่มข้อมูลเพิ่มเติมฉันคิดว่าวิธีที่ดีที่สุดที่จะคิดว่ามันเป็นข้อโต้แย้งของคำสั่ง: คุณตั้งใจจะให้ "สวัสดี" และ "โลก" เป็นสองข้อโต้แย้งหรือ "สวัสดีโลก" เพื่อเป็นหนึ่ง การโต้เถียง.

นอกจากนี้ doublequotes ยังอนุญาตให้ตีความมากกว่าตัวแปร สิ่งที่ขึ้นอยู่กับเชลล์ของคุณ แต่ตรวจสอบในการขยายประวัติการขยายรั้งและการขยายชื่อไฟล์

สิ่งสำคัญคือต้องทราบว่ามีบางกรณีที่คุณจำเป็นต้องใช้ทั้งสองประเภทของคำพูดในอาร์กิวเมนต์เดียว จำไว้ว่าข้อโต้แย้ง (โดยค่าเริ่มต้น) นั้นคั่นด้วยช่องว่างดังนั้นถ้าคุณไม่เว้นช่องว่างคุณยังคงระบุอาร์กิวเมนต์เดียวกัน

กลไกการอัญประกาศเดี่ยวของเชลล์ส่วนใหญ่ไม่อนุญาตให้ใช้สำหรับอักขระพิเศษใด ๆ ซึ่งหมายความว่าอินสแตนซ์ใด ๆ ของ singlequote อื่นแม้ว่าจะดูเหมือนว่าจะหนีออกมา ดังนั้นจึงเป็นไปไม่ได้ที่จะส่งผ่านสตริงด้วย singlequote ภายในสตริง singlequote และคุณต้องใช้ doublequote นี่อาจเป็นความเจ็บปวดเมื่อคุณต้องการผ่านการโต้แย้งที่มี singlequotes และสิ่งที่จะตีความ แต่คุณไม่ต้องการที่จะ ตัวอย่างเช่นหากคุณต้องการส่งสตริงตัวอักษร "` '$ VAR' เป็นตัวแปร "คุณต้องทำเช่นนี้:

"'"'$VAR'"' is a variable"

ที่จริงแล้วการรวมกันของสามสายอักขระที่มีเครื่องหมายคำพูดหนี:

"'"
'$VAR'
"' is a variable"

หรือเมื่อลบเครื่องหมายคำพูด:

'
$VAR
' is a variable

จริงๆแล้วด้วยกระสุนส่วนใหญ่คุณสามารถทำเช่นนี้ได้:

"'\$VAR' is a variable"

โดยที่เครื่องหมายแบ็กสแลช (" \") บอกให้เชลล์ยอมรับอักขระต่อไปนี้อย่างแท้จริงและไม่ขยายส่วนใด ๆ

แต่มีบางกรณีที่คุณต้องทำมันด้วยวิธีการเรียงต่อกันแบบหลายสายไม่ใช่ว่าฉันสามารถหาตัวอย่างได้จริงตอนนี้

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