텍스트 파일에서 $ {} 자리 표시자를 바꾸는 방법?


163

"템플릿"파일의 출력을 MySQL로 파이프하고 싶습니다 ${dbName}. 이 파일에는 산재 된 것과 같은 변수가 있습니다. 이러한 인스턴스를 바꾸고 출력을 표준 출력으로 덤프하는 명령 줄 유틸리티는 무엇입니까?

답변:


192

세드 !

주어진 template.txt :

숫자는 $ {i}입니다
단어는 $ {word}입니다

우리는 다음과 같이 말해야합니다.

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

-e이 동일한 sed호출에 여러 인수를 전달하는 Jonathan Leffler에게 감사합니다 .


13
이 두 가지 sed 명령을 하나로 결합 할 수 있습니다. sed -e "s / \ $ {i} / 1 /"-e "s / \ $ {word} / dog /"; 더 효율적입니다. sed의 일부 버전에서 100 개 정도의 이러한 작업으로 문제가 발생할 수 있습니다 (몇 년 전부터 발생했지만 문제는 아니지만 실제로는 HP-UX에주의하십시오).
Jonathan Leffler

1
감사합니다 Jonathan, 내가 찾던 것입니다.
Dana the Sane

3
작은 힌트 : 주어진 예에서 "1"또는 "dog"에 달러 기호가 포함되어 있으면 백 슬래시로 이스케이프 처리해야합니다 (그렇지 않으면 교체가 발생하지 않음).
MatthieuP

9
또한 필요하지 않습니다 cat. 당신이 필요한 전부입니다 sed -e "s/\${i}/1/" -e "s/\${word}/dog/" template.text.
HardlyKnowEm

3
대체 텍스트가 비밀번호 인 경우 어떻게합니까? 이 경우 sed번거로운 이스케이프 텍스트가 필요합니다.
jpbochi

177

최신 정보

다음은 $ VAR 또는 $ {VAR}과 같은 변수를 대체하는 간단한 질문에 대한 yottatsa 의 솔루션 이며 간단한 한 줄짜리입니다.

i=32 word=foo envsubst < template.txt

물론 i단어 가 당신의 환경에 있다면, 그것은 단지

envsubst < template.txt

내 Mac에서는 gettext의 일부로 MacGPG2 에서 설치된 것처럼 보입니다.

기존 답변

비슷한 질문에 대한 mogsie 솔루션의 개선 사항은 다음과 같습니다 . 내 솔루션에는 큰 따옴표를 escale 할 필요가 없으며 mogsie는하지만 하나는 라이너입니다!

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

이 두 가지 솔루션의 장점은 일반적으로 $ ((...)),`...`및 $ (...)가 아닌 몇 가지 유형의 셸 확장 만 얻을 수 있다는 것 입니다 . 여기서 문자를 이스케이프 처리하지만 구문 분석에 버그가 있다는 것을 걱정할 필요는 없으며 여러 줄을 올바르게 수행합니다.


6
envsubstenvar을 내 보내지 않으면 베어 가 작동하지 않습니다.
Toddius Zho 2019

4
@ ToddiusZho : 내 보내지 않은 환경 변수와 같은 것은 없습니다-정확하게 변수를 내보내 변수를 환경 변수로 만듭니다. envsubst이름에서 알 수 있듯이 변수가 아닌 환경 변수 만 인식 합니다 . 또한 가치는 주목할 것 A는 GNU의 유틸리티, 따라서 모든 플랫폼에 사전 설치 또는 사용할 수 없습니다. envsubst
mklement0

2
다른 방법으로 envsubst는 자체 프로세스 환경 변수 만 볼 수 있으므로 이전에 정의한 "일반"쉘 변수는 "내보내기"하지 않으면 자식 프로세스에서 상속하지 않습니다. 위의 gettext 사용 예에서는 상속 된 gettext 환경을 bash 메커니즘을 통해 실행하려고하는 명령 앞에
붙여서 수정

1
$ HOME이있는 문자열이 하나 있습니다. $ HOME이 기본 쉘로 작동하고 대신 $ HOME 대신 내 / home / zw963으로 작동하지만 $ (cat / etc / hostname) 대체를 지원하지 않는 것 같습니다. 그래서 그것은 내 자신의 요구와 일치하지 않습니다.
zw963

3
변수뿐만 아니라 $ (ls -l)와 같은 쉘 명령을 허용하기 때문에 "Old Answer"에 감사합니다
Alek

46

사용하십시오 /bin/sh. 변수를 설정하는 작은 쉘 스크립트를 작성한 다음 쉘 자체를 사용하여 템플리트를 구문 분석하십시오. 이와 같이 (개행을 올바르게 처리하도록 편집) :

파일 template.txt :

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

파일 script.sh :

#!/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"

산출:

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

2
왜 안돼 : 라인을 읽는 동안; eval echo "$ line"; 완료 <./template.txt ??? 전체 파일을 메모리로 읽을 필요가 없으며 머리와 꼬리를 집중적으로 사용하여 한 번에 한 줄씩 뱉어 낼 수 있습니다. 그러나 템플릿에 백 따옴표와 같은 쉘 문자가 포함되어 있지 않으면 'eval'은 괜찮습니다.
Jonathan Leffler

16
이것은 매우 위험합니다! bash입력의 모든 명령이 실행됩니다. 템플릿이 "단어 : rm -rf $ HOME"인 경우 파일을 잃게됩니다.
rzymek

1
@rzymek-이 파일을 데이터베이스에 직접 파이프하려고합니다. 겉보기에는 입력이 신뢰할 수 있습니다.
gnud

4
@gnud 파일 내용을 저장하기에 충분한 파일을 신뢰하는 것과 파일에 포함 된 것을 실행하기에 충분히 신뢰하는 것에는 차이가 있습니다.
Mark

3
제약 조건을 참고하려면 : (a) 입력의 큰 따옴표는 조용히 폐기됩니다. (b) read작성된 명령은 각 줄에서 선행 및 후행 공백을 \ 자르고 'eats' 문자를 자릅니다 . (c) 완전히 사용하는 경우에만 사용하십시오. 입력에 포함 된 명령 대체 ( `…` 또는 $(…))는의 사용으로 인해 임의의 명령을 실행할 수 있기 때문에 입력을 신뢰하거나 제어합니다 eval. 마지막으로, echo명령 행 옵션 중 하나의 행 시작 을 착각 할 가능성이 적습니다 .
mklement0

23

최근 관심사를 감안할 때 이것에 대해 다시 생각하고 있었고 원래 생각했던 도구는 m4autotools의 매크로 프로세서 라고 생각 합니다. 따라서 원래 지정한 변수 대신 다음을 사용합니다.

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

1
이 솔루션에는 여기에 대한 답변의 단점이 거의 없습니다. 그래도 DBNAME 대신 $ {DBNAME}을 (를) 바꾸는 방법을 알고 있습니까?
잭 데이비슨

@JackDavidson envsubst다른 답변에서 언급 했듯이이 간단한 변수 대체 / 템플릿 사용법에 사용합니다. m4훌륭한 도구이지만 훨씬 더 많은 기능을 갖춘 본격적인 전 처리기이므로 일부 변수를 간단히 바꾸려는 경우에는 필요하지 않을 수도 있습니다.
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
다른 곳에서 언급 한 것처럼 : 입력에 포함 된 명령 대체 ( `…` 또는 $(…))는을 사용하여 임의의 명령을 실행하고을 사용 eval하여 셸 코드를 직접 실행할 수 있으므로 입력 을 완전히 신뢰하거나 제어하는 ​​경우에만 사용하십시오 source. 또한 입력의 큰 따옴표는 조용히 삭제되므로 echo명령 줄 옵션 중 하나로 줄의 시작 부분을 오인 할 수 있습니다.
mklement0

불행히도 결과 파일에서 모든 큰 따옴표 ( ")를 제거합니다. 큰 따옴표를 제거하지 않고 동일한 방법을 사용할 수 있습니까?
Ivaylo Slavov

내가 찾던 것을 여기에서 찾았습니다. stackoverflow.com/a/11050943/795158 ; 나는 envsubst를 사용했습니다. 차이점은 var를 내 보내야한다는 것입니다.
Ivaylo Slavov 11

텍스트 파일에 "`"또는 "."가 포함 된 경우 , substitude가 실패합니다.
Shuiqiang

12

여기의 강력한 배쉬 기능을 사용하면에도 불구하고 - 있음 eval- 안전해야 사용이.

${varName}입력 텍스트의 모든 변수 참조는 호출 쉘의 변수를 기반으로 확장됩니다.

다른 건 확장되지 않습니다 : 어느 변수 이름이되는 참조 하지 묶인 {...}(예 $varName)도 명령 대체 ( $(...)레거시 구문 `...`)이나 산술 대체 ( $((...))레거시 구문 $[...]).

$리터럴로 취급하려면 \이스케이프 처리하십시오. 예 :\${HOME}

입력은 stdin을 통해서만 허용됩니다 .

예:

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

기능 소스 코드 :

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
}

함수에는없는 것으로 가정 0x1, 0x2, 0x30x4그 때문에 문자 제어 문자 입력에 존재한다. 함수는 텍스트를 처리하기 때문에 내부적으로 사용되므로 안전한 가정이어야합니다.


2
이것은 가장 좋은 대답 중 하나입니다. 사용하더라도 eval매우 안전합니다.
anubhava

1
이 솔루션은 JSON 파일과 함께 작동합니다! ( "올바로 탈출 !)
WBAR

2
이 솔루션의 좋은 점은 누락 된 변수의 기본값을 제공 ${FOO:-bar}하거나 설정된 경우에만 출력하는 것 ${HOME+Home is ${HOME}}입니다. 나는 그것이 또한 변수를 누락 종료 코드를 반환 할 수있는 약간의 확장으로 생각 ${FOO?Foo is missing}하지만, 현재 사용하지 않는 tldp.org/LDP/abs/html/parameter-substitution.html가 그 도움이된다면 이들의 목록을 가지고
스튜어트 무어

11

작성 rendertemplate.sh:

#!/usr/bin/env bash

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

그리고 template.tmpl:

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

템플릿을 렌더링합니다 :

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

2
이것은 큰 따옴표로 묶인 문자열을 제거합니다
vrtx54234

시도 : eval "echo $ (cat $ 1)"-따옴표없이, 그것은 나를 위해 일했습니다.
access_granted

2
보안 측면에서 이것은 나쁜 소식입니다. 템플릿에가 포함되어 있으면 $(rm -rf ~)코드로 실행중인 것입니다.
Charles Duffy

eval "echo \"$(cat $1)\"" 잘 작동합니다!
dev devv

10

다음은 이전 답변을 기반으로 한 펄을 사용한 솔루션이며 환경 변수를 대체합니다.

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

2
대단하다. 항상 펄이있는 것은 아니지만 그렇게 할 때 간단하고 간단합니다.
Aaron McMillin 's

5

Perl 을 사용할 수 있다면 제 제안이 될 것입니다. 아마도 sed 및 / 또는 AWK 전문가가 아마도 훨씬 더 쉬운 방법을 알고있을 것입니다. 대체를 위해 dbName 이상으로 더 복잡한 맵핑이있는 경우이를 쉽게 확장 할 수 있지만이 시점에서 표준 Perl 스크립트에 넣을 수도 있습니다.

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

약간 더 복잡한 작업을 수행하는 짧은 Perl 스크립트 (여러 키 처리) :

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

위의 스크립트 이름을 replace-script로 지정하면 다음과 같이 사용할 수 있습니다.

replace-script < yourfile | mysql

1
단일 변수에서는 작동하지만 다른 변수에는 '또는'을 어떻게 포함합니까?
Dana the Sane

2
얼마나 복잡하고 안전한지에 따라 perl을 사용하여 여러 가지 방법을 사용할 수 있습니다. 더 복잡한 예제는 여기에서 찾을 수 있습니다 : perlmonks.org/?node_id=718936
보 Simensen

3
펄을 사용하는 것이 쉘을 사용하는 것보다 훨씬 깨끗합니다. 언급 된 다른 쉘 기반 솔루션을 사용하는 대신이 작업을 수행하는 데 시간을 투자하십시오.
jdigital

1
최근에 비슷한 문제를 해결해야했습니다. 결국 나는 perl과 함께 갔다 (envsubst는 조금 유망한 것처럼 보였지만 통제하기가 너무 어려웠다).
sfitts

5

다음은 파일의 내용이 큰 따옴표 사이에 입력 된 것처럼 쉘이 대체를 수행하도록하는 방법입니다.

내용과 함께 template.txt의 예를 사용하여 :

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

다음 줄은 셸이 template.txt의 내용을 보간하여 결과를 표준 출력에 씁니다.

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

설명:

  • i그리고 word실행 환경 변수로 전달됩니다 sh.
  • sh 전달 된 문자열의 내용을 실행합니다.
  • 서로 옆에 쓰여진 문자열은 하나의 문자열이됩니다. 해당 문자열은 다음과 같습니다.
    • ' echo "'+ " $(cat template.txt)"+ ' "'
  • 대체는 사이에 있기 때문에 "" $(cat template.txt)"의 출력이 cat template.txt됩니다.
  • 따라서 실행되는 명령 sh -c은 다음과 같습니다.
    • echo "The number is ${i}\nThe word is ${word}",
    • 여기서, iword지정된 환경 변수이다.

보안 측면에서 이것은 나쁜 소식입니다. 예를 들어 '$(rm -rf ~)'$(rm -rf ~)템플릿에 템플릿 파일의 리터럴 따옴표는 확장 전에 추가 한 따옴표와 일치합니다.
Charles Duffy

템플릿 내 따옴표가 템플릿 외부 따옴표와 일치하지 않습니다. 쉘이 템플릿과 터미널 내 문자열을 독립적으로 해결하고 (따옴표를 효과적으로 제거) 연결합니다. 홈 디렉토리를 삭제하지 않는 테스트 버전은입니다 '$(echo a)'$(echo a). 생산합니다 'a'a. 무슨 일이 일어나고 중요한 것은 처음이다 echo a안쪽은 '당신이에 이후 기대하지 않을 수있는 평가를지고 '있지만, 포함과 같은 동작입니다 'A의 "인용 된 문자열.
Apriori

따라서 템플릿 작성자가 코드를 실행할 수 있다는 점에서 안전하지 않습니다. 그러나 인용문이 평가되는 방식은 실제로 보안에 영향을 미치지 않습니다. "인용 문자열 (을 포함하여 $(...))을 확장하는 것이 요점입니다.
Apriori

그게 요점인가요? ${varname}보안 위험이 높은 다른 확장을 요구하는 것만이 아닙니다 .
Charles Duffy

... 즉, 나는 달라야합니다 (재 : 템플릿 내 및 템플릿 외부 인용이 일치 할 수 있음). 문자열에 작은 따옴표를 넣으면 작은 따옴표 echo "로 묶은 문자열과 따옴표가 붙은 큰 따옴표로 묶은 문자열 template.txt, 그리고 다른 리터럴 문자열이 뒤에 오는 "단일 인수로 연결된 따옴표로 묶 습니다 sh -c. 당신은 '일치 할 수없는 것이 맞습니다 (내부 쉘로 전달되지 않고 외부 쉘에서 소비 "되었으므로). 그렇게 할 수 있으므로 템플릿을 포함하는 템플릿을 Gotcha"; rm -rf ~; echo "실행할 수 있습니다.
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
백 슬래시가 선행하는 경우 템플릿에서 명령 대체를 실행하기 때문에 안전하지 않습니다. 예\$(date)
Peter Dolberg

1
Peter의 유효한 요점을 제외하고 : 나는 명령으로 사용 while IFS= read -r line; do하는 것이 좋습니다 read. 그렇지 않으면 각 입력 줄에서 앞뒤 공백을 제거합니다. 또한 echo명령 줄 옵션 중 하나에 대한 줄 시작 부분을 오해 할 수 있으므로 사용하는 것이 좋습니다 printf '%s\n'. 마지막으로 큰 따옴표를 사용하는 것이 더 안전합니다 ${1}.
mklement0

4

Sigil 과 같은 것을 사용하는 것이 좋습니다 : https://github.com/gliderlabs/sigil

단일 바이너리로 컴파일되므로 시스템에 설치하기가 매우 쉽습니다.

그런 다음 다음과 같은 간단한 단일 라이너를 수행 할 수 있습니다.

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

이것은 eval정규식을 사용하는 것보다 훨씬 안전 하고 쉽습니다.sed


2
좋은 답변입니다! 적절한 템플릿 시스템이며 다른 답변보다 작업하기가 훨씬 쉽습니다.
Erfan

BTW, 피하고 cat사용 <my-file.conf.template하는 것이 좋습니다 sigil.FIFO 대신 실제 파일 핸들 을 제공 하십시오.
Charles Duffy

2

같은 것을 궁금해 하면서이 실을 발견했습니다. 그것은 나에게 영감을주었습니다 (백틱에주의하십시오)

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

4
bash는 속기를 위해 $(cat file)입니다$(< file)
글렌 잭맨

3
분명히이 방법은 줄 바꿈을 엉망으로 만듭니다. 즉, 내 파일이 모두 한 줄로 에코되었습니다.
Arthur Corenzan

@ArthurCorenzan : 실제로 줄 바꿈은 공백으로 바뀝니다. 이 문제를 해결하려면 사용해야 eval echo "\"$(cat FILE)\""하지만 입력의 큰 따옴표는 버려지기 때문에 여전히 부족할 수 있습니다.
mklement0

다른 곳에서 언급 한 것처럼 : 입력에 포함 된 명령 대체 ( `…` 또는 $(…))는의 사용으로 인해 임의의 명령을 실행할 수 있으므로 입력 을 완전히 신뢰하거나 제어하는 ​​경우에만 사용하십시오 eval.
mklement0

2

여기에 많은 선택이 있지만 힙에 내 것을 던질 것이라고 생각했습니다. 펄 기반이며 $ {...} 형식의 변수 만 대상으로하고 파일을 인수로 처리하여 stdout에서 변환 된 파일을 출력합니다.

use Env;
Env::import();

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

print "$text";

물론 나는 실제로 펄 사람이 아니기 때문에 치명적인 결함이 쉽게 생길 수 있습니다 (그러나 나를 위해 작동합니다).


1
잘 작동합니다. Env::import();라인 가져 오기를 삭제할 수 use있습니다. 또한 메모리에 전체 출력을 먼저 구성하지 않는 것이 좋습니다 . 루프 내부 print;대신 대신 사용 $text .= $_;하고 포스트 루프 print명령을 삭제하십시오 .
mklement0

1

구성 파일 형식을 제어 할 수있는 경우 bash 자체에서 수행 할 수 있습니다. 구성 파일을 서브 쉘이 아닌 소스 ( ".")로 지정하면됩니다. 그러면 변수가 서브 쉘 (서브 쉘이 종료 될 때 변수가 사라지는)이 아닌 현재 쉘의 컨텍스트에서 작성되고 계속 존재합니다.

$ 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

설정 파일이 쉘 스크립트가 될 수 없다면, 실행하기 전에 '컴파일'하면됩니다 (컴파일은 입력 형식에 따라 다릅니다).

$ 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

특정 경우에는 다음과 같은 것을 사용할 수 있습니다.

$ 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

그런 다음 go.bash의 출력을 MySQL과 voila로 파이프하면 데이터베이스를 손상시키지 않기를 바랍니다 :-).


1
config.data 파일에서 변수를 내보낼 필요는 없습니다. 그것들을 설정하는 것만으로 충분합니다. 당신은 또한 언제라도 템플릿 파일을 읽지 않는 것 같습니다. 또는 템플릿 파일이 수정되어 '에코'작업이 포함되어 있거나 뭔가 빠졌습니까?
Jonathan Leffler

1
수출에 대한 좋은 지적은 기본적으로 하위 쉘에서 사용할 수 있도록하고 있으며 종료시 죽기 때문에 해를 끼치 지 않습니다. '템플릿'파일은 스크립트 자체이며 echo 문입니다. 세 번째 파일을 도입 할 필요가 없습니다. 기본적으로 mailmerge 유형 작업입니다.
paxdiablo 2016 년

1
"에코 문이있는 스크립트 자체"는 템플릿이 아닙니다. 스크립트입니다. <xml type = "$ TYPE">과 echo '<xml type = "'$ TYPE '">'의 가독성 (및 유지 관리 성) 차이를 생각하십시오
Pierre-Olivier Vares

1
@Pierre, 내 구성 스크립트에는 echo 문이 없으며 단순히 내보내기 일 뿐이며 최소한의 전처리로도 피할 수있는 방법을 보여주었습니다. 내 다른 스크립트 (예 :)에서 echo 문에 대해 이야기하고 있다면 go.bash스틱의 끝이 잘못되었습니다. 이것은 솔루션의 일부가 아니며 변수가 있다는 것을 보여주는 방법 일뿐입니다 올바르게 설정하십시오.
paxdiablo

1
@paxdiablo : 당신은 질문을 잊어 버린 것 같습니다 : << "템플릿"파일의 출력을 MySQL로 파이프하고 싶습니다 >> 따라서 템플릿을 사용하는 것이 문제입니다. "스틱의 잘못된 끝"이 아닙니다. 변수를
내보내고

0

백업을 통해 잠재적으로 여러 파일을 펄 편집 할 수 있습니다.

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

0

제한된 현재 사용 사례에서 작동하지만 더 복잡한 상황에서는 충분하지 않기 때문에 현재 제안보다 더 강력한 것을 원할 것입니다.

더 나은 렌더러가 필요합니다. 최고의 렌더러가 필요합니다. 당신은 Renderest가 필요합니다!

주어진 template.txt :

안녕하세요, {{person}}!

운영:

$ person = Bob ./render template.txt

그리고 당신은 출력을 볼 수 있습니다

안녕 밥!

stdout을 파일로 리디렉션하여 파일에 씁니다.

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

그리고 보간하고 싶지 않은 $ {} 변수가있는 스크립트를 렌더링하는 경우 다른 작업을 수행하지 않고도 Renderest를 사용할 수 있습니다!

https://github.com/relaxdiego/renderest 에서 계속해서 사본을 받으십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.