grep ตีความถูก $ อย่างไร


12

เมื่อฉันเขียน

$ grep \$  

เมื่อใดก็ตามที่ฉันพิมพ์บนเทอร์มินัลจะจับคู่และพิมพ์บนเทอร์มินัล เป็นวิธีการ\$ที่ถูกตีความ?

คำตอบ:


18

เปลือกจะถูกตีความ\$และผ่านมันผ่านไป grep เป็น$จุดสิ้นสุดของตัวละครสาย ดังนั้นสมมติว่าบรรทัดของคุณมีที่สิ้นสุดมันจะจับคู่ :-)

หากคุณต้องการจับคู่$grep จริงให้ใช้หนึ่งใน:

grep \\\$
grep '\$'

ในอดีตเปลือกตีความ\\เป็น\และ\$เป็นให้$ \$ในระยะหลังมันไม่ได้ตีความเลย


สำหรับคำถามของคุณว่าทำไม\$จับคู่เครื่องหมายดอลลาร์แทนลำดับสองอักขระนิพจน์ทั่วไปเช่นที่ใช้ในการgrepใช้อักขระพิเศษสำหรับวัตถุประสงค์บางอย่าง บางส่วนของเหล่านี้คือ:

$       end of line
^       start of line
.       any character
+       1 or more of the preceeding pattern
*       0 or more of the preceeding pattern
{n,m}   between n and m of the preceeding pattern
[x-y]   any character between x and y (such as [0-9] for a digit).

พร้อมกับคนอื่น ๆ อีกมากมาย

เมื่อคุณต้องการจับคู่อักขระตัวอักษรลาที่ปกติถือว่าเป็นอักขระพิเศษคุณต้องหลบหนีเพื่อที่grepจะถือว่าเป็นอักขระปกติ


1
เพื่อทดสอบสิ่งที่ grep เห็นลองecho \$แล้วecho \\$

ใน grep \\\ $ ตามที่คุณบอกว่า \ $ จะถูกส่งไปยัง grep ดังนั้นจึงควรจับคู่สตริงที่มี \ $ แต่ทำไมมันถึงตรงกับสตริงที่มี $ เท่านั้น?

เพราะ $ in grep หมายถึงจุดสิ้นสุดของบรรทัด เพื่อให้ตรงกับอักขระ $ คุณต้องหลีกเลี่ยงมันเพื่อให้ grep ไม่จัดการเป็นพิเศษ ดูการปรับปรุงของฉัน

@Pasi: echo ทำ unescaping ของตัวเองขึ้นอยู่กับว่ามันเป็น shell builtin หรือไม่, เป็นไปตาม POSIX หรือไม่และอื่น ๆ ที่ดีกว่าคือ (IMHO) ที่จะใช้ls \$และดูว่าเราได้รับ "ls: $: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว" เพื่อดูว่า \ $ ไม่ได้รับการยกเว้นค่าสถานะเป็น $ แต่ \\ $ จะไม่ได้รับการยกเว้นค่าสถานะเป็น $ $ และอื่น ๆ
Henno

5

เชลล์เริ่มขยาย escape sequences ก่อนที่จะส่งอาร์กิวเมนต์ไปที่โปรแกรมดังนั้นมันจะตีความ\$ว่าเป็น escape sequences และส่งอาร์กิวเมนต์เดียว$ไปgrepที่ซึ่งตรงกับจุดสิ้นสุดของบรรทัด เนื่องจากทุกบรรทัดมีจุดสิ้นสุดดังนั้นทุกบรรทัดควรจับคู่ :)


แต่วิธี $ จะสิ้นสุดบรรทัด? จุดสิ้นสุดของบรรทัดไม่ใช่ \ n ใช่หรือไม่

2
@Happy Mithal: ดูman grep; มันได้รับการตัดสินใจที่$ตรงกับปลายสายโดยไม่คำนึงถึงหรือไม่ว่าเส้นจะถูกคั่นด้วย\n, \rทั้งสองหรือบางสิ่งบางอย่างที่แตกต่างกันอย่างสิ้นเชิง ในกรณีทั่วไปนิพจน์ทั่วไปสามารถใช้เพื่อจับคู่สตริงใด ๆ ไม่ใช่แค่“ บรรทัด” และ$ใช้เพื่อจับคู่ส่วนท้ายของสตริง

2

มันกำลังถูกตีความว่าเป็นตัวบ่งชี้ที่สิ้นสุดของบรรทัด หากคุณต้องการจับคู่เครื่องหมายดอลลาร์ที่แท้จริงให้ทำ

 $ grep \\$ 

หรือ

 $ grep '\$' 

1

^สำหรับจุดเริ่มต้นของสตริงและ$สำหรับจุดสิ้นสุด

grep \$

หรือ

grep $

จะจับคู่ทุกสตริงดังนั้นสิ่งที่คุณพิมพ์จะถูกสะท้อนกลับ

ลอง

grep a$

ตอนนี้สายเดียวที่มีตัวอักษรตัวสุดท้ายจะถูกaจะถูกจับคู่และสะท้อน


1

คุณสามารถบันทึกปัญหาในการหลบหนีหากคุณต้องการค้นหาตัวอักษร$โดยใช้นิพจน์ปกติสำหรับคลาสอักขระ ตัวอย่างเช่น,

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