ฉันใช้โค้ดด้านล่างเพื่อแทนที่สตริงภายในเชลล์สคริปต์
echo $LINE | sed -e 's/12345678/"$replace"/g'
แต่มันถูกแทนที่ด้วย$replace
แทนค่าของตัวแปรนั้น
มีใครบอกได้ไหมว่าเกิดอะไรขึ้น?
ฉันใช้โค้ดด้านล่างเพื่อแทนที่สตริงภายในเชลล์สคริปต์
echo $LINE | sed -e 's/12345678/"$replace"/g'
แต่มันถูกแทนที่ด้วย$replace
แทนค่าของตัวแปรนั้น
มีใครบอกได้ไหมว่าเกิดอะไรขึ้น?
คำตอบ:
หากคุณต้องการตีความ$replace
คุณไม่ควรใช้เครื่องหมายคำพูดเดี่ยวเนื่องจากจะป้องกันการแทนที่ตัวแปร
ลอง:
echo $LINE | sed -e "s/12345678/\"${replace}\"/g"
สมมติว่าคุณต้องการใส่เครื่องหมายคำพูดหากคุณไม่ต้องการคำพูดให้ใช้:
echo $LINE | sed -e "s/12345678/${replace}/g"
การถอดเสียง:
pax> export replace=987654321
pax> echo X123456789X | sed "s/123456789/${replace}/"
X987654321X
pax> _
เพียงระมัดระวังเพื่อให้แน่ใจว่า${replace}
ไม่มีอักขระใด ๆ ที่มีความสำคัญsed
(เช่น/
เช่น) เนื่องจากจะทำให้เกิดความสับสนเว้นแต่จะหลีกหนี แต่ถ้าอย่างที่คุณบอกว่าคุณกำลังแทนที่หมายเลขหนึ่งด้วยหมายเลขอื่นก็ไม่น่าจะเป็นปัญหา
set
ก็ไม่จำเป็นเช่นกัน (แล้วคุณจะใช้มันอย่างไร?) เพียงreplace=987654321
.
export
เพื่อให้แน่ใจว่ามีการตั้งค่าตัวแปรสำหรับเด็ก แต่อย่างที่คุณพูดคุณสามารถหลีกเลี่ยงได้อย่างง่ายดาย อย่างไรก็ตามการใช้หรือไม่ใช้ไม่export
เกี่ยวข้องกับที่นี่ (ปัญหาเกี่ยวกับสไตล์) และไม่มีผลต่อคำตอบจริงซึ่งเป็นวิธีการใช้ตัวแปรภายในsed
คำสั่ง
-i
ตัวเลือกนี้ คุณจะรู้ว่าทำไม? หรือจะทำให้มันทำงานได้อย่างไร?
$
หรือ`
ในsed
สคริปต์ที่จะหลีกเลี่ยงด้วยแบ็กสแลชเพื่อป้องกันจากกลไกการแทนที่ของเชลล์สำหรับสตริงที่ยกมาสองครั้ง
คุณสามารถใช้เชลล์ (bash / ksh)
$ var="12345678abc"
$ replace="test"
$ echo ${var//12345678/$replace}
testabc
/bin/sh
ใน Linuxes ที่ทันสมัยจำนวนมาก
ไม่เฉพาะเจาะจงสำหรับคำถาม แต่สำหรับผู้ที่ต้องการฟังก์ชั่นประเภทเดียวกันขยายเพื่อความชัดเจนจากคำตอบก่อนหน้า
# create some variables
str="someFileName.foo"
find=".foo"
replace=".bar"
# notice the the str isn't prefixed with $
# this is just how this feature works :/
result=${str//$find/$replace}
echo $result
# result is: someFileName.bar
str="someFileName.sally"
find=".foo"
replace=".bar"
result=${str//$find/$replace}
echo $result
# result is: someFileName.sally because ".foo" was not found
คำคมโสดมาแรงมาก เมื่อเข้าไปข้างในแล้วคุณไม่สามารถทำอะไรได้เพื่อเรียกใช้การแทนที่ตัวแปรจนกว่าคุณจะออกไป ใช้เครื่องหมายคำพูดคู่แทน:
echo $LINE | sed -e "s/12345678/$replace/g"
echo $LINE | sed -e 's/12345678/'$replace'/g'
คุณยังสามารถใช้อัญประกาศเดี่ยวได้ แต่คุณต้อง "เปิด" เมื่อคุณต้องการให้ตัวแปรขยายในตำแหน่งที่ถูกต้อง มิฉะนั้นจะใช้สตริง "ตามตัวอักษร" (ตามที่ @paxdiablo ระบุไว้อย่างถูกต้องคำตอบของเขาก็ถูกต้องเช่นกัน)
$replace
นอกเครื่องหมายคำพูดใด ๆ จะทำให้เชลล์ดำเนินการเว้นวรรคโทเค็นและการขยายสัญลักษณ์แทนค่า สิ่งนี้ดูเหมือนจะใช้งานได้กับค่าที่เรียบง่าย แต่สามารถระเบิดได้อย่างมากในสตริงที่ไม่สำคัญ อย่าใช้สิ่งนี้ในรหัสการผลิต
เพื่อให้เชลล์ของคุณขยายตัวแปรคุณต้องใช้เครื่องหมายคำพูดคู่เช่น
sed -i "s#12345678#$replace#g" file.txt
สิ่งนี้จะแตกหาก$replace
มีsed
อักขระพิเศษ( #
, \
) แต่คุณสามารถประมวลผลล่วงหน้า$replace
เพื่ออ้างถึง:
replace_quoted=$(printf '%s' "$replace" | sed 's/[#\]/\\\0/g')
sed -i "s#12345678#$replace_quoted#g" file.txt
ฉันมีข้อกำหนดที่คล้ายกันนี้ แต่การแทนที่ var ของฉันมีเครื่องหมายแอมเพอร์แซนด์ การหลีกเลี่ยงเครื่องหมายและวิธีนี้ช่วยแก้ปัญหาของฉัน:
replace="salt & pepper"
echo "pass the salt" | sed "s/salt/${replace/&/\&}/g"
ใช้สิ่งนี้แทน
echo $LINE | sed -e 's/12345678/$replace/g'
สิ่งนี้ใช้ได้กับฉันเพียงแค่ลบคำพูด
ฉันชอบใช้เครื่องหมายคำพูดคู่เนื่องจาก quptes เดี่ยวมีประสิทธิภาพมากเมื่อเราใช้หากไม่สามารถเปลี่ยนแปลงอะไรภายในนั้นหรือสามารถเรียกใช้การแทนที่ตัวแปรได้
ดังนั้นให้ใช้เครื่องหมายคำพูดคู่
echo $LINE | sed -e "s/12345678/$replace/g"