Metin dosyasında $ {} yer tutucuları nasıl değiştirilir?


163

Bir "şablon" dosyasının çıktısını MySQL, boru ${dbName}serpiştirilmiş gibi değişkenlere sahip olmak istiyorum . Bu örnekleri değiştirmek ve çıktıyı standart çıktıya dökmek için komut satırı yardımcı programı nedir?

Yanıtlar:


192

Sed !

Verilen template.txt:

Sayı $ {i}
Kelime $ {word}

sadece şunu söylemeliyiz:

sed -e "s/\${i}/1/" -e "s/\${word}/dog/" template.txt

Bahşişin -eaynı sedçağrıyı birden fazla tartışmaya aktarması için Jonathan Leffler'a teşekkürler .


13
Bu iki sed komutunu bir araya getirebilirsiniz: sed -e "s / \ $ {i} / 1 /" -e "s / \ $ {word} / dog /"; bu daha verimlidir. Belki bu tür 100 operasyonda sed'in bazı sürümleriyle sorun yaşayabilirsiniz (yıllar önce sorun - hala doğru olmayabilir, ancak HP-UX'e dikkat edin).
Jonathan Leffler

1
Teşekkürler Jonathan, tam olarak aradığım şey.
Dana the Sane

3
Küçük ipucu: verilen örnekteki "1" veya "köpek" bir dolar simgesi içeriyorsa, ters eğik çizgi ile kaçmanız gerekir (aksi takdirde değiştirme gerçekleşmez).
MatthieuP

9
Ayrıca gerek yok cat. Tek ihtiyacınız olan şey sed -e "s/\${i}/1/" -e "s/\${word}/dog/" template.text.
HardlyKnowEm

3
Değiştirilen metin bir şifre ise ne olur? Bu durumda, sedbir güçlük olan kaçan bir metin beklenir.
jpbochi

177

Güncelleme

İşte benzer bir soruda yottatsa'dan sadece $ VAR veya $ {VAR} gibi değişkenlerin yerini alan ve kısa bir tek satırlık bir çözüm

i=32 word=foo envsubst < template.txt

Tabii ben ve kelime çevrenizdeyse, o zaman sadece

envsubst < template.txt

O bir parçası olarak yüklendiği gibi benim Mac'te görünüyor gettext ve gelen MacGPG2

Eski Cevap

İşte benzer bir soru üzerinde mogsie'den çözümde bir iyileştirme , benim çözümüm çift tırnak, esnaf gerektirmez, mogsie yapar, ama onun bir astar!

eval "cat <<EOF
$(<template.txt)
EOF
" 2> /dev/null

Bu iki çözümler üzerinde güç ters eğik çizgi gerçi sadece, (...) meydana gelmez kabuk yorumlarından birkaç türde normalde $ ((...)), `...` almak ve $ olmasıdır olan bir kaçış karakteri burada, ancak ayrıştırma bir hata var endişelenmenize gerek yok ve birden çok satır gayet iyi yapıyor.


6
envsubstEnvarlarınız ihraç edilmezse çıplak işe yaramıyor.
Toddius Zho

4
@ToddiusZho: Dışa aktarılmayan bir ortam değişkeni diye bir şey yoktur - bir kabuk değişkenini bir ortam değişkeni yapan tam olarak dışa aktarır . envsubst, adından da anlaşılacağı gibi, kabuk değişkenlerini değil , yalnızca ortam değişkenlerini tanır . Ayrıca , bir GNU yardımcı programı olduğunu ve bu nedenle tüm platformlara önceden yüklenmemiş veya mevcut olmadığını belirtmek gerekir . envsubst
mklement0

2
Söylemenin başka bir yolu, envsubst'un yalnızca kendi işlem ortamı değişkenlerini görmesidir, bu nedenle daha önce tanımlamış olabileceğiniz "normal" kabuk değişkenleri (ayrı satırlarda), "dışa aktarmazsanız" alt süreçler tarafından miras alınmaz. Yukarıdaki gettext örnek kullanımımda, devralınan gettext ortamını bash mekanizması aracılığıyla çalıştırmak üzere olduğum komuta ekleyerek değiştiriyorum
plockc 25:15

1
İçinde $ HOME olan bir dize var, $ HOME'un varsayılan kabuk olarak çalıştığını, bunun yerine $ HOME'u kendi / home / zw963 olarak buldum, ancak $ (cat / etc / hostname) değiştirmeyi desteklemiyor gibi görünüyor, kendi talebime uygun değil.
zw963

3
"Eski Cevap" için teşekkürler, sadece değişkenlere izin vermekle kalmaz, aynı zamanda $ (ls -l)
Alek

46

Kullanın /bin/sh. Değişkenleri ayarlayan küçük bir kabuk komut dosyası oluşturun ve ardından kabuğun kendisini kullanarak şablonu ayrıştırın. Bunun gibi (yeni satırları doğru işlemek için düzenleyin):

Dosya şablonu.txt:

the number is ${i}
the word is ${word}

Script.sh dosyası:

#!/bin/sh

#Set variables
i=1
word="dog"

#Read in template one line at the time, and replace variables (more
#natural (and efficient) way, thanks to Jonathan Leffler).
while read line
do
    eval echo "$line"
done < "./template.txt"

Çıktı:

#sh script.sh
the number is 1
the word is dog

2
Neden sadece: satır okurken; eval echo "$ line" yapın; bitti. <template.txt ??? Tüm dosyayı belleğe okumaya gerek yok, sadece kafa ve kuyruğu yoğun bir şekilde kullanarak bir kerede bir satır tükürmek için. Ancak 'eval' tamam - şablon geri tırnak işaretleri gibi kabuk karakterler içermiyorsa.
Jonathan Leffler

16
Bu çok tehlikeli! Girişteki tüm bashkomut yürütülür. Şablon: "kelimeler; rm -rf $ HOME" ise dosyaları kaybedersiniz.
rzymek

1
@rzymek - unutmayın, bu dosyayı doğrudan veritabanına aktarmak istiyor. Görünüşe göre, giriş güvenilir.
gnud

4
@gnud Bir dosyanın içeriğini depolayacak kadar güvenin ve içerdiği her şeyi yürütecek kadar güvendiği arasında bir fark vardır.
Mark

3
Kısıtlamaları not etmek için: (a) girişteki çift tırnak işaretleri sessizce atılır, (b) readkomut, yazıldığı gibi, her satırdan baştaki ve sondaki boşlukları keser ve 'yiyor' \ karakterleri., (C) bunu yalnızca tamamen girdiye güvenin veya kontrol edin, çünkü girdiye gömülü komut ikameleri ( `…` veya $(…)), kullanımından dolayı keyfi komutların yürütülmesine izin verir eval. Son olarak, echokomut satırı seçeneklerinden biri için bir satırın başlangıcında hata yapma olasılığı küçüktür .
mklement0

23

Yakın zamandaki ilgi göz önüne alındığında, bu konuyu tekrar düşünüyordum ve ilk başta düşündüğüm aracın, m4otoklavların makro işlemcisi olduğunu düşünüyorum . Yani başlangıçta belirttiğim değişken yerine şunu kullanırsınız:

$echo 'I am a DBNAME' | m4 -DDBNAME="database name"

1
Bu çözüm, cevapların en az dezavantajına sahiptir. Yine de sadece DBNAME yerine $ {DBNAME} yerine geçmenin herhangi bir yolunu biliyor musunuz?
Jack Davidson

@JackDavidson envsubstBu basit değişken değiştirme / şablonlama kullanımı için diğer cevaplarda belirtildiği gibi kullanacağım . m4harika bir araçtır, ancak çok daha fazla özelliğe ve karmaşıklığa sahip, sadece bazı değişkenleri değiştirmek istiyorsanız gerekli olmayabilecek tam gelişmiş bir ön işlemcidir.
imiric

13

template.txt

Variable 1 value: ${var1}
Variable 2 value: ${var2}

data.sh

#!/usr/bin/env bash
declare var1="value 1"
declare var2="value 2"

parser.sh

#!/usr/bin/env bash

# args
declare file_data=$1
declare file_input=$2
declare file_output=$3

source $file_data
eval "echo \"$(< $file_input)\"" > $file_output

./parser.sh data.sh template.txt parsed_file.txt

parsed_file.txt

Variable 1 value: value 1
Variable 2 value: value 2

1
Başka bir yerde belirtildiği gibi: Bunu yalnızca girdiye tam olarak güvenirseniz veya kontrol ederseniz kullanın, çünkü girişe gömülü komut ikameleri ( `…` veya $(…)) kullanımı nedeniyle rasgele komutların evalyürütülmesine ve kullanımından dolayı kabuk kodunun doğrudan yürütülmesine izin verir source. Ayrıca, girişteki çift tırnak işaretleri sessizce atılır ve echokomut satırı seçeneklerinden biri için bir satırın başlangıcında hata yapabilir.
mklement0

Ne yazık ki, bu sonuç dosyadan tüm çift tırnak ( ") şeritler çift tırnak çıkarmadan aynı yapmanın bir yolu var mı.?
Ivaylo Slavov

Burada aradığım şeyi buldum: stackoverflow.com/a/11050943/795158 ; Envsubst kullandım. Aradaki fark, varyasyonların benimle olan iyi ihraç edilmesi gerektiğidir.
Ivaylo Slavov

metin dosyası "" "veya" "içeriyorsa. , ikame başarısız olur.
shuiqiang

12

İşte , kullanmasına rağmen - kullanımının güvenli olması gereken sağlam bir Bash işlevieval .

${varName}Giriş metnindeki tüm değişken referanslar, çağrılan kabuğun değişkenlerine göre genişletilir.

Başka bir şey genişletilmemiştir: ne isimleri (örneğin ) içine alınmayan değişken referanslar , ne komut ikameleri ( ve eski sözdizimi ), ne de aritmetik ikameler ( ve eski sözdizimi ).{...}$varName$(...)`...`$((...))$[...]

A'yı $gerçek olarak ele almak için \-görünümü; Örneğin:\${HOME}

Girişin sadece stdin ile kabul edildiğini unutmayın .

Misal:

$ expandVarsStrict <<<'$HOME is "${HOME}"; `date` and \$(ls)' # only ${HOME} is expanded
$HOME is "/Users/jdoe"; `date` and $(ls)

İşlev kaynak kodu:

expandVarsStrict(){
  local line lineEscaped
  while IFS= read -r line || [[ -n $line ]]; do  # the `||` clause ensures that the last line is read even if it doesn't end with \n
    # Escape ALL chars. that could trigger an expansion..
    IFS= read -r -d '' lineEscaped < <(printf %s "$line" | tr '`([$' '\1\2\3\4')
    # ... then selectively reenable ${ references
    lineEscaped=${lineEscaped//$'\4'{/\${}
    # Finally, escape embedded double quotes to preserve them.
    lineEscaped=${lineEscaped//\"/\\\"}
    eval "printf '%s\n' \"$lineEscaped\"" | tr '\1\2\3\4' '`([$'
  done
}

Fonksiyon hiçbir varsayar 0x1, 0x2, 0x3ve 0x4bu karakter çünkü kontrol karakterleri, giriş mevcuttur. dahili olarak kullanılır - işlev metni işlediğinden , bu güvenli bir varsayım olmalıdır.


2
Buradaki en iyi cevaplardan biri bu. Kullanırken bile evalkullanımı oldukça güvenlidir.
anubhava

1
Bu çözüm JSON dosyalarıyla çalışır! ( "düzgün kaçıyor !)
WBAR

2
Bu çözümle ilgili hoş bir şey, eksik değişkenler için varsayılanlar sağlamanıza ${FOO:-bar}veya yalnızca ayarlanmışsa bir şey çıktılamanıza izin vermesidir ${HOME+Home is ${HOME}}. Küçük bir uzantı ile eksik değişkenler için de çıkış kodları döndürebileceğinden şüpheleniyorum ${FOO?Foo is missing}ama şu anda tldp.org/LDP/abs/html/parameter-substitution.html yardımcı oluyorsa bunların bir listesine sahip
Stuart Moore

11

Oluşturun rendertemplate.sh:

#!/usr/bin/env bash

eval "echo \"$(cat $1)\""

Ve template.tmpl:

Hello, ${WORLD}
Goodbye, ${CHEESE}

Şablonu oluştur:

$ export WORLD=Foo
$ CHEESE=Bar ./rendertemplate.sh template.tmpl 
Hello, Foo
Goodbye, Bar

2
Bu çift tırnaklı dizeleri şeritler
vrtx54234 14:18

Denedim: eval "echo $ (cat $ 1)" - tırnak işaretleri olmadan ve benim için çalıştı.
access_granted

2
Güvenlik açısından bu kötü bir haber. Şablonunuz içeriyorsa $(rm -rf ~), bunu kod olarak çalıştırıyorsunuz demektir.
Charles Duffy

eval "echo \"$(cat $1)\"" Harika çalışıyor!
dev devv

10

işte benim önceki cevaba dayanan perl ile benim çözümüm, ortam değişkenlerini değiştirir

perl -p -e 's/\$\{(\w+)\}/(exists $ENV{$1}?$ENV{$1}:"missing variable $1")/eg' < infile > outfile

2
Bu harika. Her zaman perl'e sahip olmayın, ancak bunu yaptığınızda, bu basit ve basittir.
Aaron McMillin

5

Perl'i kullanmaya açıksanız , bu benim önerim olacaktır. Her ne kadar muhtemelen bunu daha kolay yapacağını bilen bazı sed ve / veya AWK uzmanları olmasına rağmen . Değiştirmeleriniz için sadece dbName'den daha karmaşık bir eşlemeniz varsa, bunu oldukça kolay bir şekilde genişletebilirsiniz, ancak bu noktada standart bir Perl betiğine de koyabilirsiniz.

perl -p -e 's/\$\{dbName\}/testdb/s' yourfile | mysql

Biraz daha karmaşık bir şey yapmak için kısa bir Perl betiği (birden fazla tuşu kullanın):

#!/usr/bin/env perl
my %replace = ( 'dbName' => 'testdb', 'somethingElse' => 'fooBar' );
undef $/;
my $buf = <STDIN>;
$buf =~ s/\$\{$_\}/$replace{$_}/g for keys %replace;
print $buf;

Yukarıdaki komut dosyasını değiştirme komut dosyası olarak adlandırırsanız, daha sonra aşağıdaki gibi kullanılabilir:

replace-script < yourfile | mysql

1
Tek değişkenler için çalışır, ancak diğerleri için 'veya' nasıl eklerim?
Dana the Sane

2
Bunu perl ile yapmanın birçok yolu vardır, hepsi bunu ne kadar karmaşık ve / veya güvenli yapmak istediğinize bağlı olarak. Daha karmaşık örnekler burada bulunabilir: perlmonks.org/?node_id=718936
Beau Simensen

3
Perl kullanmak, kabuğu kullanmaya çalışmaktan çok daha temiz. Bahsedilen diğer kabuk tabanlı çözümlerden bazılarını denemek yerine bu işi yapmak için zaman harcayın.
jdigital

1
Son zamanlarda benzer bir sorunu çözmek zorunda kaldı. Sonunda perl ile gitti (envsubst biraz umut verici görünüyordu, ama kontrol etmek çok zordu).
2014'te

5

Kabuğun sizin için ikame yapmasını sağlamanın bir yolu, sanki dosyanın içeriği çift tırnak arasına yazılmıştır.

Template.txt örneğini içeriklerle kullanma:

The number is ${i}
The word is ${word}

Aşağıdaki satır kabuğun template.txt içeriğini enterpolasyona ve sonucu standart çıktıya yazmasına neden olacaktır.

i='1' word='dog' sh -c 'echo "'"$(cat template.txt)"'"'

Açıklama:

  • ive wordortam değişkenleri yürütülmesine atlanır olarak geçirilir sh.
  • sh iletildiği dizenin içeriğini yürütür.
  • Yan yana yazılan dizeler bir dize haline gelir, bu dize:
    • ' echo "' + " $(cat template.txt)" + ' "'
  • İkame arasında olduğu için ", " $(cat template.txt)" çıktısı olur cat template.txt.
  • Böylece yürütülen komut sh -c:
    • echo "The number is ${i}\nThe word is ${word}",
    • nerede ive wordbelirtilen ortam değişkenleridir.

Güvenlik açısından bu kötü bir haber. Şablonunuz, örneğin, '$(rm -rf ~)'$(rm -rf ~)şablon dosyasındaki gerçek tırnaklar genişletilmeden önce eklediklerinizle eşleşir.
Charles Duffy

Ben şablon içinde tırnaklar şablon kalıp tırnak eşleşen, ben kabuk şablon ve terminal içi dize bağımsız olarak (tırnak kaldırma etkili) sonra onları bitirme çözmektedir inanıyorum. Testin ana dizininizi silmeyen bir sürümü '$(echo a)'$(echo a). Üretir 'a'a. Oluyor Önemli olan ilk olmasıdır echo aiçeride 'sen İçinde beri beklediğiniz olmayabilir, hangi değerlendirilir oluyor ', ancak dahil aynı davranıştır 'bir de "alıntı dize.
Apriori

Bu nedenle, şablon yazarının kodunu çalıştırmasına izin vermesi açısından güvenli değildir. Ancak tekliflerin nasıl değerlendirildiği güvenliği gerçekten etkilemez. Herhangi bir şeyi genişletmek bir "-quoted string (dahil $(...)).
Apriori

Mesele bu mu? Onları sadece ${varname}daha yüksek güvenlik riski açılımları istemek için görüyorum .
Charles Duffy

... dedi ki, farklı olmalıyım (yeniden: şablon içi ve şablon dışı tırnaklar eşleşebiliyor). Eğer dizede tek alıntı koyduğunuzda, tek tırnaklar içine konum bölme echo "edebi contetns ile çift tırnaklar ardından template.txtbaşka değişmez dize ardından ", tüm geçirilen tek argüman içine birleştirilmiş sh -c. Eşleşemeyeceğiniz konusunda haklısınız '(iç kabuğa geçmek yerine dış kabuk tarafından tüketildiğinden), ancak "kesinlikle yapabilir, böylece içeren bir şablon Gotcha"; rm -rf ~; echo "yürütülebilir.
Charles Duffy

4

file.tpl:

The following bash function should only replace ${var1} syntax and ignore 
other shell special chars such as `backticks` or $var2 or "double quotes". 
If I have missed anything - let me know.

script.sh:

template(){
    # usage: template file.tpl
    while read -r line ; do
            line=${line//\"/\\\"}
            line=${line//\`/\\\`}
            line=${line//\$/\\\$}
            line=${line//\\\${/\${}
            eval "echo \"$line\""; 
    done < ${1}
}

var1="*replaced*"
var2="*not replaced*"

template file.tpl > result.txt

2
Bu güvenli değildir, çünkü önde gelen ters eğik çizgileri varsa şablonda komut ikameleri uygulayacaktır, örneğin\$(date)
Peter Dolberg

1
Peter'ın geçerli noktasının yanı sıra: Komut while IFS= read -r line; doolarak kullanmanızı öneririm read, aksi takdirde her giriş satırından önde gelen ve sondaki boşlukları çıkarırsınız. Ayrıca, echokomut satırı seçeneklerinden biri için bir satırın başlangıcında hata yapabilir, bu nedenle kullanmak daha iyidir printf '%s\n'. Son olarak, çift teklif vermek daha güvenlidir ${1}.
mklement0

4

Sigil gibi bir şey kullanmanızı öneririm : https://github.com/gliderlabs/sigil

Tek bir ikili dosyaya derlenmiştir, bu nedenle sistemlere kurmak son derece kolaydır.

Daha sonra aşağıdaki gibi basit bir tek astar yapabilirsiniz:

cat my-file.conf.template | sigil -p $(env) > my-file.conf

Bu, evalregex kullanmaktan daha güvenli ve kolaydır.sed


2
Mükemmel cevap! Bu uygun bir şablon sistemidir ve diğer cevaplardan daha kolay çalışılır.
Erfan

BTW, bunun yerine kaçınmak catve kullanmak daha iyidir, <my-file.conf.templateböylece sigilFIFO yerine gerçek bir dosya tanıtıcısı verirsiniz .
Charles Duffy

2

Aynı şeyi merak ederken bu konuyu buldum. Bana bu konuda ilham verdi (backticks'e dikkat et)

$ echo $MYTEST
pass!
$ cat FILE
hello $MYTEST world
$ eval echo `cat FILE`
hello pass! world

4
Bir bash kısaltmadır için $(cat file)ise$(< file)
glenn Jackman

3
Görünüşe göre bu yöntem satır sonları ile karışıklık, yani benim dosya tüm bir satırda yankılandı.
Arthur Corenzan

@ArthurCorenzan: Gerçekten de satır sonları boşluklarla değiştiriliyor. Bunu düzeltmek için kullanmanız gerekir, eval echo "\"$(cat FILE)\""ancak yine de girişteki çift tırnakların atılması nedeniyle kısa sürebilir.
mklement0

Başka bir yerde belirtildiği gibi: Bunu yalnızca girdiye tam olarak güveniyorsanız veya kontrol ediyorsanız kullanın, çünkü girişe gömülü komut ikameleri ( `…` veya $(…)) , nedeniyle rasgele komutların yürütülmesine izin verir eval.
mklement0

2

Burada bir sürü seçenek var, ama öbek benim fırlatmak düşündüm. Perl tabanlıdır, yalnızca $ {...} biçimindeki değişkenleri hedefler, dosyayı argüman olarak işlemek için alır ve dönüştürülen dosyayı stdout'ta çıkarır:

use Env;
Env::import();

while(<>) { $_ =~ s/(\${\w+})/$1/eeg; $text .= $_; }

print "$text";

Tabii ki gerçekten perl insan değilim, bu yüzden kolayca ölümcül bir kusur olabilir (benim için çalışıyor olsa da).


1
İyi çalışıyor. Env::import();Satırı bırakabilirsiniz - içe aktarma ima edilir use. Ayrıca, önce tüm çıktıyı bellekte oluşturmamanızı öneririm: döngü içinde kullanmak print;yerine $text .= $_;döngü sonrası printkomutunu bırakın .
mklement0 25.03.2015

1

Konfigürasyon dosyası formatı kontrolünüz varsa bash'ın kendisinde yapılabilir. Yapılandırma dosyasını alt kabuk yerine kaynaklamak (".") Yapmanız yeterlidir. Bu, değişkenlerin alt kabuktan ziyade geçerli kabuk bağlamında oluşturulmasını (ve var olmaya devam etmesini) sağlar (değişken, alt kabuk çıktığında kaybolur).

$ cat config.data
    export parm_jdbc=jdbc:db2://box7.co.uk:5000/INSTA
    export parm_user=pax
    export parm_pwd=never_you_mind

$ cat go.bash
    . config.data
    echo "JDBC string is " $parm_jdbc
    echo "Username is    " $parm_user
    echo "Password is    " $parm_pwd

$ bash go.bash
    JDBC string is  jdbc:db2://box7.co.uk:5000/INSTA
    Username is     pax
    Password is     never_you_mind

Eğer yapılandırma dosyanız bir kabuk betiği olamazsa, onu çalıştırmadan önce sadece 'derleyebilirsiniz' (derleme giriş formatınıza bağlıdır).

$ cat config.data
    parm_jdbc=jdbc:db2://box7.co.uk:5000/INSTA # JDBC URL
    parm_user=pax                              # user name
    parm_pwd=never_you_mind                    # password

$ cat go.bash
    cat config.data
        | sed 's/#.*$//'
        | sed 's/[ \t]*$//'
        | sed 's/^[ \t]*//'
        | grep -v '^$'
        | sed 's/^/export '
        >config.data-compiled
    . config.data-compiled
    echo "JDBC string is " $parm_jdbc
    echo "Username is    " $parm_user
    echo "Password is    " $parm_pwd

$ bash go.bash
    JDBC string is  jdbc:db2://box7.co.uk:5000/INSTA
    Username is     pax
    Password is     never_you_mind

Özel durumunuzda aşağıdaki gibi bir şey kullanabilirsiniz:

$ cat config.data
    export p_p1=val1
    export p_p2=val2
$ cat go.bash
    . ./config.data
    echo "select * from dbtable where p1 = '$p_p1' and p2 like '$p_p2%' order by p1"
$ bash go.bash
    select * from dbtable where p1 = 'val1' and p2 like 'val2%' order by p1

Sonra go.bash çıktısını MySQL ve voila'ya aktarın, umarım veritabanınızı yok etmezsiniz :-).


1
Değişkenleri config.data dosyasından dışa aktarmanız gerekmez; onları ayarlamak yeterlidir. Ayrıca hiçbir zaman şablon dosyasını okumuyor gibi görünmüyorsunuz. Veya, şablon dosyası değiştirilir ve 'echo' işlemlerini içerir ... yoksa bir şey mi kaçırıyorum?
Jonathan Leffler

1
İhracatta iyi bir nokta, bunu varsayılan olarak yapıyorum, böylece alt kabuklar için kullanılabilirler ve gittiklerinde öldüklerinden zarar vermezler. 'Template' dosyası, echo deyimlerinin bulunduğu komut dosyasının kendisidir. Üçüncü bir dosya eklemeye gerek yoktur - temelde bir hanımefendi tipi işlemdir.
paxdiablo

1
"Komutun yankı ifadeleriyle kendisi" bir şablon değildir: bir komut dosyasıdır. <Xml type = "$ TYPE"> ve echo '<xml type = "' $ TYPE '">>
Pierre-Olivier Vares

1
@Pierre, yapılandırma komut dosyamda yankı ifadeleri yok, sadece dışa aktarılıyorlar ve minimum miktarda ön işleme ile bundan nasıl kaçınabileceğinizi gösterdim. Diğer komut dosyalarımdaki (örneğin go.bash) yankı ifadesinden bahsediyorsanız , çubuğun yanlış ucuna sahipsiniz - çözümün bir parçası değiller, sadece değişkenlerin var olduğunu göstermenin bir yolu doğru şekilde ayarlayın.
paxdiablo

1
@paxdiablo: Görünüşe göre şu soruyu unuttun: << Bir "şablon" dosyasının çıktısını MySQL'e aktarmak istiyorum >>. Yani bir şablon kullanmak soru, "çubuğun yanlış sonu" değil. Değişkenleri İhracat ve başka komut bunları yankılanan soruya cevap vermez hiç
Pierre-Olivier Vareš

0

Yerinde, birden fazla dosyanın yedeklemelerle perl düzenlemesi.

  perl -e 's/\$\{([^}]+)\}/defined $ENV{$1} ? $ENV{$1} : ""/eg' \
    -i.orig \
    -p config/test/*

0

Mevcut önerilerden daha sağlam bir şey isteyeceksiniz, çünkü (şimdilik) sınırlı kullanım durumunuz için çalışırken, daha karmaşık durumlar için yeterli olmayacaklardır.

Daha iyi bir oluşturucuya ihtiyacınız var. En iyi renderere ihtiyacınız var. Renderest'e ihtiyacınız var!

Verilen template.txt:

Merhaba insan}}!

Çalıştırmak:

$ person = Bob ./render template.txt

Ve çıktıyı göreceksiniz

Merhaba Bob!

Stdout'u bir dosyaya yönlendirerek bir dosyaya yazın:

$ person = Bob ./render template.txt> rendered.txt

Ve enterpolasyon yapılmasını istemediğiniz $ {} değişkenleri olan bir komut dosyası oluşturuyorsanız, Renderest başka bir şey yapmanıza gerek kalmadan sizi ele geçirdi!

Devam edin ve https://github.com/relaxdiego/renderest adresinden kopyanızı alın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.