ใช้ sed กับเครื่องหมาย & (&)


19

ฉันใช้ sed เพื่อค้นหาและแทนที่รูปแบบภายในไฟล์ SAS ที่ฉันมีแทนที่จะเปลี่ยนทีละรายการ ปัญหาคือฉันพยายามแทนที่ตัวแปรมาโครและเมื่อฉันใช้เครื่องหมายและมันไม่ได้ประมวลผลอย่างถูกต้อง

Here's my code:
sed -ie 's/user=&uid./user=&sysuserid./g' *_table_*.sas

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

คำถาม: ฉันจะแทนที่ข้อความที่มีเครื่องหมายภายในด้วยคำสั่ง sed ได้อย่างไร


6
&เป็นตัวละครพิเศษดังนั้นจึงจำเป็นต้องหลบหนีเมื่อใช้ใน RHS - ในกรณีของคุณคุณต้องวิ่ง 's/user=&uid./user=\&sysuserid./g'แม้ว่าฉันสงสัยว่าคุณยังต้องหลบหนีจุดใน LHS เพื่อให้ตรงกับจุดตามตัวอักษรดังนั้นคุณต้อง's/user=&uid\./user=\&sysuserid./g'
don_crissti

1
ใช่แล้ว '&' ทางด้านขวาโดยทั่วไปหมายถึง "ทุกสิ่งที่เข้าคู่กันทางซ้าย" ดังนั้นให้หลบหนีด้วย '\' คุณควรทำให้คำตอบนั้นไม่ใช่แค่ความคิดเห็น
Edward Falk

ฉันไม่จำเป็นต้องหลบหนีในช่วงแรก ... เพียงแค่หัวขึ้นในคนอื่นก็อยากรู้อยากเห็น :)
lucasdavis500

คำตอบ:


25

&เป็นพิเศษในการแทนข้อความ: มันหมายความว่า“ส่วนทั้งหมดของการป้อนข้อมูลที่ตรงตามรูปแบบ” ดังนั้นสิ่งที่คุณกำลังทำอะไรที่นี่แทนที่ด้วยuser=&uidX user=user=&uidXsysuserid.การใส่เครื่องหมายที่เกิดขึ้นจริงในการแทนที่ข้อความ, \&การใช้งาน

อีกสิ่งหนึ่งที่ดูเหมือนผิดคือ.ในรูปแบบการค้นหาหมายถึงอักขระใด ๆ (ยกเว้นบรรทัดใหม่) แต่.ท้ายที่สุดของข้อความการแทนที่คือจุดตัวอักษร หากคุณต้องการแทนที่สตริงตัวอักษรเท่านั้นให้user=&uid.ป้องกัน.ด้วยแบ็กสแลช

sed -e 's/user=&uid\./user=\&sysuserid./g'

หากคุณต้องการแทนที่อักขระหนึ่งตัวและเก็บไว้ในผลลัพธ์ให้ใส่อักขระในกลุ่มและใช้\1ในการแทนที่เพื่ออ้างถึงกลุ่มนั้น

sed -e 's/user=&uid\(.\)/user=\&sysuserid\1/g'

ในความเป็นจริงจากการทำซ้ำระหว่างข้อความต้นฉบับและการแทนที่คุณควรใช้กลุ่มต่อไป:

sed -e 's/\(user=&\)u\(id\.\)/\1sysuser\2/g'

เช่น“ แทนที่uด้วยsysuserระหว่างuser=&และid.


คุณอธิบายกลุ่มได้ไหม
lucasdavis500

2
@ lucasdavis500 กลุ่มหนึ่งระบุส่วนของลวดลาย มันคั่นด้วยเครื่องหมายแบ็กสแลช - วงเล็บ ตัวอย่างเช่น\(user=&\)รูปแบบที่จับคู่user&และเก็บสตริงการจับคู่เป็นกลุ่ม (หมายเลขกลุ่ม 1 เนื่องจากเป็นกลุ่มแรกในรูปแบบ) จากนั้นในการแทนที่จะ\1ถูกแทนที่ด้วยสตริงที่เก็บไว้สำหรับกลุ่มหมายเลข 1
Gilles 'ดังนั้น - หยุดความชั่วร้าย'

คุณหมายถึง (user = &) ร้านค้า user = & ไม่ใช่ผู้ใช้ &?
lucasdavis500

@ lucasdavis500 ฉันไม่เข้าใจความคิดเห็นของคุณ ตัวอักษร=ในการแสดงออกปกติและในการแทนที่ข้อความหมายถึงตัวเองดังนั้นการuser=&จับคู่เท่านั้นuser=&และuser=&ในการแทนที่ข้อความผลผลิตuser=ตามด้วยส่วนหนึ่งของบรรทัดที่จับคู่โดย regex
Gilles 'หยุดความชั่วร้าย' ใน

1
@ lucasdavis500 =ตัวละครไม่มีความหมายพิเศษ user=&ในข้อความที่สร้างuser=ขึ้นแทนที่ตามด้วยข้อความต้นฉบับที่ตรงกัน user=\&ในข้อความที่สร้างขึ้นใหม่user=&
Gilles 'หยุดความชั่วร้าย'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.