ในขณะที่พยายามค้นหารูปแบบง่าย ๆ "สวัสดี" ในไฟล์รูปแบบของ grep ต่อไปนี้ทั้งหมดทำงาน:
- grep สวัสดี file1
- grep 'hello' file1
- grep "hello" file1
มีกรณีเฉพาะที่หนึ่งในรูปแบบข้างต้นทำงานได้ แต่คนอื่นไม่ มันสร้างความแตกต่างหรือไม่ถ้าฉันใช้อันอื่น?
ในขณะที่พยายามค้นหารูปแบบง่าย ๆ "สวัสดี" ในไฟล์รูปแบบของ grep ต่อไปนี้ทั้งหมดทำงาน:
มีกรณีเฉพาะที่หนึ่งในรูปแบบข้างต้นทำงานได้ แต่คนอื่นไม่ มันสร้างความแตกต่างหรือไม่ถ้าฉันใช้อันอื่น?
คำตอบ:
สิ่งนี้ขึ้นอยู่กับเปลือกของคุณ คำพูด (ทั้งสองประเภท) มีวัตถุประสงค์เพื่อจัดการกับช่องว่างเป็นหลัก ตัวอย่างเช่นต่อไปนี้:
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
$
เป็นจุดสิ้นสุดของบรรทัดในนิพจน์ทั่วไปดังนั้น$VAR1
ไม่ควรจับคู่กับสิ่งใดเลย มันเกิดขึ้นกับการทำงานกับ GNU grep แต่ฉันก็ยังไม่เชื่อในพฤติกรรมนั้น คุณจะต้อง\$VAR1
จับคู่สตริงตัวอักษรให้ปลอดภัย (และคุณจะต้อง backslashes พิเศษถ้าที่อยู่ในคำพูดสอง.)
James ถูกต้อง แต่เพื่อเพิ่มข้อมูลเพิ่มเติมฉันคิดว่าวิธีที่ดีที่สุดที่จะคิดว่ามันเป็นข้อโต้แย้งของคำสั่ง: คุณตั้งใจจะให้ "สวัสดี" และ "โลก" เป็นสองข้อโต้แย้งหรือ "สวัสดีโลก" เพื่อเป็นหนึ่ง การโต้เถียง.
นอกจากนี้ doublequotes ยังอนุญาตให้ตีความมากกว่าตัวแปร สิ่งที่ขึ้นอยู่กับเชลล์ของคุณ แต่ตรวจสอบในการขยายประวัติการขยายรั้งและการขยายชื่อไฟล์
สิ่งสำคัญคือต้องทราบว่ามีบางกรณีที่คุณจำเป็นต้องใช้ทั้งสองประเภทของคำพูดในอาร์กิวเมนต์เดียว จำไว้ว่าข้อโต้แย้ง (โดยค่าเริ่มต้น) นั้นคั่นด้วยช่องว่างดังนั้นถ้าคุณไม่เว้นช่องว่างคุณยังคงระบุอาร์กิวเมนต์เดียวกัน
กลไกการอัญประกาศเดี่ยวของเชลล์ส่วนใหญ่ไม่อนุญาตให้ใช้สำหรับอักขระพิเศษใด ๆ ซึ่งหมายความว่าอินสแตนซ์ใด ๆ ของ singlequote อื่นแม้ว่าจะดูเหมือนว่าจะหนีออกมา ดังนั้นจึงเป็นไปไม่ได้ที่จะส่งผ่านสตริงด้วย singlequote ภายในสตริง singlequote และคุณต้องใช้ doublequote นี่อาจเป็นความเจ็บปวดเมื่อคุณต้องการผ่านการโต้แย้งที่มี singlequotes และสิ่งที่จะตีความ แต่คุณไม่ต้องการที่จะ ตัวอย่างเช่นหากคุณต้องการส่งสตริงตัวอักษร "` '$ VAR' เป็นตัวแปร "คุณต้องทำเช่นนี้:
"'"'$VAR'"' is a variable"
ที่จริงแล้วการรวมกันของสามสายอักขระที่มีเครื่องหมายคำพูดหนี:
"'"
'$VAR'
"' is a variable"
หรือเมื่อลบเครื่องหมายคำพูด:
'
$VAR
' is a variable
จริงๆแล้วด้วยกระสุนส่วนใหญ่คุณสามารถทำเช่นนี้ได้:
"'\$VAR' is a variable"
โดยที่เครื่องหมายแบ็กสแลช (" \
") บอกให้เชลล์ยอมรับอักขระต่อไปนี้อย่างแท้จริงและไม่ขยายส่วนใด ๆ
แต่มีบางกรณีที่คุณต้องทำมันด้วยวิธีการเรียงต่อกันแบบหลายสายไม่ใช่ว่าฉันสามารถหาตัวอย่างได้จริงตอนนี้