นี่เป็นคำถามเก่า แต่ไม่มีคำตอบใดที่จะกล่าวถึงการดำเนินการนอกเหนือจากs/from/to/รายละเอียดมากนัก
รูปแบบทั่วไปของsedคำสั่งคือ
*address* *action*
โดยที่อยู่อาจเป็นช่วงนิพจน์ทั่วไปหรือช่วงหมายเลขบรรทัด (หรือว่างซึ่งในกรณีนี้การดำเนินการจะถูกนำไปใช้กับทุกบรรทัดอินพุต) ตัวอย่างเช่น
sed '1,4d' file
จะลบบรรทัดที่ 1 ถึง 4 (ที่อยู่คือช่วงหมายเลขบรรทัด1,4และการดำเนินการคือdคำสั่งลบ); และ
sed '/ick/,$s/foo/bar/' file
จะแทนที่การเกิดขึ้นครั้งแรกfooด้วยbarในบรรทัดใด ๆ ระหว่างการจับคู่ครั้งแรกใน regex ickและจุดสิ้นสุดของไฟล์ (ที่อยู่คือช่วง/ick/,$และการดำเนินการคือsคำสั่งแทนที่s/foo/bar/ )
ในบริบทนี้หากickมาจากตัวแปรคุณสามารถทำได้
sed "/$variable/,\$s/foo/bar/"
(สังเกตการใช้เครื่องหมายคำพูดคู่แทนคำพูดเดี่ยวเพื่อให้เชลล์สามารถสอดแทรกตัวแปรและความจำเป็นในการอ้างเครื่องหมายดอลลาร์ตามตัวอักษรภายในเครื่องหมายคำพูดคู่) แต่ถ้าตัวแปรมีเครื่องหมายทับคุณจะได้รับข้อผิดพลาดทางไวยากรณ์ (เชลล์ขยายตัวแปรจากนั้นส่งสตริงผลลัพธ์ไปยังsed; ดังนั้นsedเห็นเฉพาะข้อความตามตัวอักษร - ไม่มีแนวคิดเกี่ยวกับตัวแปรของเชลล์)
วิธีแก้คือการใช้ตัวคั่นอื่น (ซึ่งแน่นอนว่าคุณต้องสามารถใช้อักขระที่ไม่สามารถเกิดขึ้นในค่าของตัวแปรได้) แต่ไม่เหมือนในs%foo%bar%กรณีนี้คุณต้องใช้แบ็กสแลชก่อนตัวคั่นหากคุณต้องการใช้ตัวอื่น ตัวคั่นมากกว่าค่าเริ่มต้น/:
sed "\\%$variable%,\$s/foo/bar/" file
(ภายในเครื่องหมายคำพูดเดียวแบ็กสแลชเดียวก็เพียงพอแล้ว) หรือคุณสามารถแยกทุกเครื่องหมายทับในค่า ไวยากรณ์เฉพาะนี้คือ Bash เท่านั้น:
sed "/${variable//\//\\/}/,\$s/foo/bar/" file
หรือถ้าคุณใช้เปลือกอื่นให้ลอง
escaped=$(echo "$variable" | sed 's%/%\\/%g')
sed "s/$escaped/,\$s/foo/bar/" file
เพื่อความชัดเจนหาก$variableมีสตริง1/2คำสั่งข้างต้นจะเทียบเท่ากับ
sed '\%1/2%,$s/foo/bar/' file
ในกรณีแรกและ
sed '/1\/2/,$s/foo/bar/' file
ในวินาที