मानक सेड को शेल नहीं कहा जा सकता ( GNU 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
एक खोल में सीना
आप इनपुट को शेल स्क्रिप्ट में बदल सकते हैं और उसका मूल्यांकन कर सकते हैं। सैड कार्य करने के लिए है, हालांकि यह इतना आसान नहीं है। अपनी " 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
वही तकनीक जिनका इस्तेमाल हमने शामक के साथ सेड के साथ किया। परिणामी कार्यक्रम काफी पठनीय है। " 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