bash मटक फ़ाइल के प्लेसहोल्डर्स को एकल पास में भरें




मिलन मटका (4)

मैं सिर्फ इस सवाल पर ठोकर खाई क्योंकि मैं सिर्फ उसी प्रकार की तलाश कर रहा था, और मुझे envsubst(1) मिला।

यदि आप पर्यावरण चर का उपयोग नहीं करते हैं तो आप envsubst का उपयोग कर सकते हैं:

PLACEHOLDER_1='string 1' PLACEHOLDER_2='multiline 
string 
2' envsubst < output.template 

यदि आपके पास बहुत सारे चर हैं तो आप उन्हें एक फ़ाइल में स्टोर कर सकते हैं और सिर्फ इसका source (सोर्सेड फ़ाइल के अंत में export का उपयोग करना याद रखें!)

मेरे प्लेसहोल्डर स्ट्रिंग के साथ एक कंकाल टेक्स्ट फ़ाइल है:

blah blah blah
blah $PLACEHOLDER_1$
blah
$PLACEHOLDER_2$

और इसी तरह। प्लेसहोल्डर्स के विशिष्ट "फ़ॉर्म" से कोई फर्क नहीं पड़ता है - मैं उन्हें विशिष्ट कार्यान्वयन के लिए जो सबसे अधिक आरामदायक बनाता हूं, उन्हें बदल सकता हूं।

मेरे पास एक बास स्क्रिप्ट है जहां मैं प्लेसहोल्डर्स के लिए मूल्यों को जानता हूं, और मुझे एक नई फाइल बनाने की ज़रूरत है, जिसमें मूल्यों के साथ प्लेसहोल्डर्स को बदल दिया गया है।

#! /bin/sh
PLACEHOLDER_1 = 'string 1'
PLACEHOLDER_2 = 'multiline 
string 
2'
# TODO: Generate file output.txt from file output.template 
#       using placeholders above.

मैं इसे sed के साथ कई पास में कर सकता हूं, लेकिन यह मजेदार नहीं है। मैं पर्ल का उपयोग नहीं करना चाहता मैं पाठपुस्तकों का इस्तेमाल करना चाहता हूं और खुद को ही बाश करना चाहता हूं।

एक एकल पास में जो मैं चाहता हूं, सबसे अच्छा तरीका क्या है?


Sed बिना इसे करने का एक तरीका है:

सबसे पहले, एक थोड़ा संशोधित टेम्पलेट फ़ाइल जिसमें प्लेसहोल्डर बाश वेरिएबल्स हैं:

blah blah blah
blah $PLACEHOLDER_1
blah
$PLACEHOLDER_2

और स्क्रिप्ट:

#! /bin/sh
templatefile=output.template
outputfile=output.txt

PLACEHOLDER_1='string 1'

PLACEHOLDER_2='multiline 
string 
2'

# DONE: Generate file output.txt from file output.template 
#       using placeholders above.

echo "$(eval "echo \"$(cat $templatefile)\"")" > $outputfile

यह एक ऐसा संस्करण है जो स्क्रिप्ट के भीतर निहित टेम्पलेट दर्शाता है, लेकिन एक मोड़ के साथ। यह डिफ़ॉल्ट मान भी दर्शाता है, जिसे टेम्प्लेट फ़ाइल संस्करण में भी उपयोग किया जा सकता है, साथ ही आप टेम्पलेट में गणित कर सकते हैं:

#! /bin/sh
template='blah blah blah
blah $PLACEHOLDER_1
blah
${PLACEHOLDER_2:-"some text"} blah ${PLACEHOLDER_3:-"some
lines
of
text"} and the total is: $((${VAL_1:-0} + ${VAL_2:-0}))'
# default operands to zero (or 1) to prevent errors due to unset variables
outputfile=output.txt

# gears spin, bells ding, values for placeholders are computed

PLACEHOLDER_1='string 1'

PLACEHOLDER_2='multiline 
string 
2'

VAL_1=2

VAL_2=4

unset PLACEHOLDER_3 # so we can trigger one of the defaults

# Generate file output.txt from variable $template 
#       using placeholders above.

echo "$(eval "echo \"$template\"")" > $outputfile

कोई sed नहीं, कोई छोर नहीं, बस बालों वाले घोंसले के शिकार और उद्धरण मुझे पूरा यकीन है कि सभी उद्धरण आपको किसी टेम्पलेट फ़ाइल में दुर्भावनापूर्ण सामान से बचाएंगे, लेकिन मैं इसकी गारंटी नहीं दे रहा हूं।


मेरी बाश केवल समाधान:

TEMPLATE='
foo
$var1
bar
$var2'
eval "echo \"$TEMPLATE\""

पिछले उत्तर पर इमारत, शायद एक सरणी का उपयोग करें और sed स्ट्रिंग की गणना करें?

#!/bin/sh
PLACEHOLDER[0]='string 1'
PLACEHOLDER[1]='multiline 
string 
2'

s="sed -i "
for(( i=0 ; i<${#PLACEHOLDER[*]} ; i++ )) ; do 
    echo ${PLACEHOLDER[$i]}
    s=$s"s/PLACEHOLDER_$i/${PLACEHOLDER[$i]}/g;"
done
echo $s

मल्टी-लाइन स्ट्रिंग पर विफल होने लगता है, यद्यपि।

मुझे नहीं पता कि पोर्टेबल बैश एरेज़ कैसे हो सकते हैं। स्निपेट के ऊपर "जीएनयू बाश, संस्करण 3.2.17 (1) -रेलीज (i386-apple-darwin9.0)" के साथ परीक्षण किया गया





textutils