sed มาตรฐานไม่สามารถเรียกเชลล์ได้ ( GNU sed มีส่วนขยายที่ต้องทำหากคุณสนใจเฉพาะ Linux ที่ไม่ได้ฝังตัว) ดังนั้นคุณจะต้องทำการประมวลผลนอก sed มีวิธีแก้ปัญหาหลายอย่าง ทุกคนต้องมีการอ้างอิงอย่างระมัดระวัง
ยังไม่ชัดเจนว่าคุณต้องการขยายค่าอย่างไร ตัวอย่างเช่นถ้าเป็นเส้น
foo hello; echo $(true) 3
ควรส่งออกข้อมูลใดต่อไปนี้
k=<foo> value=<hello; echo 3>
k=<foo> value=<hello; echo 3>
k=<foo> value=<hello; echo 3>
k=<foo> value=<foo hello
3>
ฉันจะหารือเกี่ยวกับความเป็นไปได้หลายอย่างด้านล่าง
เปลือกบริสุทธิ์
คุณสามารถรับเชลล์เพื่ออ่านบรรทัดอินพุตโดยบรรทัดและประมวลผล นี่เป็นทางออกที่ง่ายที่สุดและเร็วที่สุดสำหรับไฟล์สั้น ๆ นี่คือสิ่งที่ใกล้เคียงกับความต้องการของคุณมากที่สุด“ echo \2
”:
while read -r keyword value; do
echo "k=<$keyword> v=<$(eval echo "$value")>"
done
read -r keyword value
ตั้งค่า$keyword
เป็นคำที่คั่นด้วยช่องว่างแรกของบรรทัดและ$value
เป็นส่วนที่เหลือของบรรทัดลบด้วยช่องว่างต่อท้าย
หากคุณต้องการที่จะขยายการอ้างอิงตัวแปร แต่ไม่ดำเนินการคำสั่งนอกแทนคำสั่งใส่$value
ภายในเอกสารที่นี่ ฉันสงสัยว่านี่คือสิ่งที่คุณกำลังมองหาจริงๆ
while read -r keyword value; do
echo "k=<$keyword> v=<$(cat <<EOF
$value
EOF
)>"
done
sed สอดเข้าไปในเปลือก
คุณสามารถแปลงอินพุตให้เป็นเชลล์สคริปต์และประเมินค่านั้น Sed ขึ้นอยู่กับภารกิจแม้ว่ามันจะไม่ใช่เรื่องง่าย ไปecho \2
ตามข้อกำหนด“ ” ของคุณ(โปรดทราบว่าเราต้องหลีกเลี่ยงการเสนอราคาเดียวในคำหลัก):
sed -e 's/^ *//' -e 'h' \
-e 's/[^ ]* *//' -e 'x' \
-e 's/ .*//' -e "s/'/'\\\\''/g" -e "s/^/echo 'k=</" \
-e 'G' -e "s/\n/>' v=\\</" -e 's/$/\\>/' | sh
ไปกับเอกสารที่นี่เรายังต้องหลีกเลี่ยงคำหลัก (แต่แตกต่างกัน)
{
echo 'cat <<EOF'
sed -e 's/^ */k=</' -e 'h' \
-e 's/[^ ]* *//' -e 'x' -e 's/ .*//' -e 's/[\$`]/\\&/g' \
-e 'G' -e "s/\n/> v=</" -e 's/$/>/'
echo 'EOF'
} | sh
นี่เป็นวิธีที่เร็วที่สุดหากคุณมีข้อมูลจำนวนมาก: มันไม่ได้เริ่มกระบวนการแยกต่างหากสำหรับแต่ละบรรทัด
awk
เทคนิคเดียวกับที่เราใช้กับ sed ทำงานด้วย awk โปรแกรมที่ได้นั้นอ่านได้ง่ายกว่ามาก ไปกับ“ echo \2
”:
awk '
1 {
kw = $1;
sub(/^ *[^ ]+ +/, "");
gsub(/\047/, "\047\\\047\047", $1);
print "echo \047k=<" kw ">\047 v=\\<" $0 "\\>";
}' | sh
ใช้เอกสารที่นี่:
awk '
NR==1 { print "cat <<EOF" }
1 {
kw = $1;
sub(/^ *[^ ]+ +/, "");
gsub(/\\\$`/, "\\&", $1);
print "k=<" kw "> v=<" $0 ">";
}
END { print "EOF" }
' | sh