ฉันเพิ่งมีปัญหากับ regex บางอย่างในบรรทัดคำสั่งและพบว่าสำหรับการจับคู่แบ็กสแลชสามารถใช้อักขระต่าง ๆ ได้ หมายเลขนี้ขึ้นอยู่กับการอ้างอิงที่ใช้สำหรับ regex (ไม่มีเครื่องหมายคำพูดเดี่ยว, เครื่องหมายคำพูดคู่) ดูเซสชั่นทุบตีต่อไปนี้สำหรับสิ่งที่ฉันหมายถึง:
echo "#ab\\cd" > file
grep -E ab\cd file
grep -E ab\\cd file
grep -E ab\\\cd file
grep -E ab\\\\cd file
#ab\cd
grep -E ab\\\\\cd file
#ab\cd
grep -E ab\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\\cd file
grep -E "ab\cd" file
grep -E "ab\\cd" file
grep -E "ab\\\cd" file
#ab\cd
grep -E "ab\\\\cd" file
#ab\cd
grep -E "ab\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\\cd" file
grep -E 'ab\cd' file
grep -E 'ab\\cd' file
#ab\cd
grep -E 'ab\\\cd' file
#ab\cd
grep -E 'ab\\\\cd' file
ซึ่งหมายความว่า:
- ฉันสามารถจับคู่แบ็กสแลชกับแบ็กสแลชที่แท้จริง 4-7
- ด้วยเครื่องหมายคำพูดคู่ฉันสามารถจับคู่แบ็กสแลชกับแบ็กสแลชที่แท้จริง 3-6
- ด้วยเครื่องหมายคำพูดเดี่ยวฉันสามารถจับคู่แบ็กสแลชกับแบ็คสแลชจริง 2-3 รายการได้
ฉันเข้าใจว่าหนึ่ง backslash พิเศษถูกละเว้นโดยเชลล์ (จากหน้า man bash):
"เครื่องหมายแบ็กสแลชที่ไม่ใช่เครื่องหมายอัญประกาศ (\) คืออักขระเลี่ยงมันจะเก็บรักษาค่าตามตัวอักษรของอักขระถัดไปที่ตามมา"
สิ่งนี้ใช้ไม่ได้กับตัวอย่างที่ยกมาเดี่ยวเนื่องจากไม่มีการหลบหนีในเครื่องหมายคำพูดเดี่ยว
และเครื่องหมายแบ็กสแลชเพิ่มเติมหนึ่งรายการจะถูกละเว้นโดยคำสั่ง grep ("\ c" เป็นเพียง "c" เท่านั้น แต่นี่ก็เหมือนกับ "c" เพราะ "c" ไม่มีความหมายพิเศษใน regex)
สิ่งนี้อธิบายพฤติกรรมของตัวอย่างด้วยเครื่องหมายคำพูดเดี่ยว แต่ฉันไม่เข้าใจอีกสองตัวอย่างโดยเฉพาะอย่างยิ่งว่าทำไมมีความแตกต่างระหว่างการที่ไม่ใช่ qouted สตริงที่มีเครื่องหมายคำพูดคู่
อ้างจากหน้า bash man อีกครั้ง:
"การใส่อักขระในเครื่องหมายคำพูดคู่จะเก็บรักษาค่าตัวอักษรของอักขระทั้งหมดภายในเครื่องหมายคำพูดยกเว้น $,`, \, และเมื่อเปิดใช้งานการขยายประวัติ,!. "
ฉันลองแบบเดียวกันกับ GNU awk (เช่นawk /ab\cd/{print} file
) ด้วยผลลัพธ์เดียวกัน
Perl อย่างไรก็ตามแสดงผลลัพธ์ที่แตกต่าง (โดยใช้ตัวอย่างperl -ne
"/ab\\cd/"\&\&print file
):
- ฉันสามารถจับคู่แบ็กสแลชกับแบ็กสแลชจริง 4-5 รายการได้
- ด้วยเครื่องหมายคำพูดคู่ฉันสามารถจับคู่แบ็กสแลชกับแบ็คสแลชจริง 3-4 รายการ
- ด้วยเครื่องหมายคำพูดเดี่ยวฉันสามารถจับคู่แบ็กสแลชกับ 2 แบ็คสแลชตามจริง
ใครสามารถอธิบายความแตกต่างระหว่างสตริง regex ที่ไม่ได้ยกมาและ double-qouted บนบรรทัดคำสั่งสำหรับ grep และ awk? ฉันไม่สนใจคำอธิบายเกี่ยวกับพฤติกรรมของ Perl เนื่องจากฉันมักจะไม่ใช้ Perl one-liners
printf "\ntest"
จะแทรกบรรทัดใหม่ก่อน "ทดสอบ" แม้ว่า"\n"
ควรจะได้รับการแปล"n"
โดยเชลล์ตามที่มันเป็น whithin อัญประกาศคู่ ... (ดังนั้นผลที่คาดหวังควรจะเป็นสำหรับ . "\ ntest", "ntest" เราควรจะได้รับนิสัยจะเขียนprintf "\\ntest"
หรือprintf '\ntest'
แต่อย่างใดฉันเห็นมากของสคริปต์อาศัยเหตุการณ์ที่แปลกประหลาดที่แทน.