이는 VAR2에 따라 업데이트되어야 하는 템플릿 변수 VAR1입니다. 변수의 순서는 다음과 같습니다. sed 명령 없이 VAR1을 업데이트하는 방법은 무엇입니까?
#!/bin/bash
VAR1="<tr>
<th>\$VAR2</th>
</tr>"
VAR2=test
echo $VAR2
답변1
당신이 사용할 수있는 envsubst
:
(포함된 POSIX 쉘을 사용하십시오 bash
):
VAR1="<tr>
<th>\$VAR2</th>
</tr>"
VAR2=test
expanded_VAR1=$(
export VAR2
printf '%s\n' "$VAR1" |
envsubst '$VAR2'
)
또는 모든 단어 확장(매개변수 확장, 명령 대체, 산술 확장)을 수행합니다.~ 위에zsh
매개변수 확장의 경우 해당 e
매개변수 확장 플래그를 사용할 수 있습니다 .
#!/bin/zsh -
VAR1="<tr>
<th>\$VAR2</th>
</tr>"
VAR2=test
expanded_VAR1=${(e)VAR1}
POSIX 셸에서는 eval
및 here-document를 사용하여 유사한 작업을 수행할 수 있습니다.
VAR1="<tr>
<th>\$VAR2</th>
</tr>"
VAR2=test
expanded_VAR1=$(eval "cat << EOF
$VAR1
EOF")
bash
또는에 대한 또 다른 옵션은 다음을 zsh
사용하는 것입니다 printf
.
VAR1='<tr>
<th>%s</th>
</tr>'
VAR2=test
printf -v expanded_VAR1 -- "$VAR1" "$VAR2"
zsh
(사용하지 않음 )을 사용하면 다음 구문을 사용하여 th 매개변수를 참조 bash
할 수 있습니다 %n$s
(많은 구현에서와 마찬가지로 ) .printf(3)
n
#! /bin/zsh -
VAR1='<tr>
<th>%1$s</th> <th>%1$s again</th> <th>%2$s</th>
</tr>'
VAR2=test VAR3=test2
printf -v expanded_VAR1 -- "$VAR1" "$VAR2" "$VAR3"
또는 명명된 형식 지시문을 사용합니다( zformat
, , NUL 및 10진수를 제외한 단일 바이트 문자로 제한됨).-
.
#! /bin/zsh -
VAR1='<tr>
<th>%a</th> <th>%a again</th> <th>%b</th>
</tr>'
VAR2=test VAR3=test2
zformat -f expanded_VAR1 "$VAR1" "a:$VAR2" "b:$VAR3"
를 사용하면 대신 를 사용하여 HTML의 특수 문자(예: be )를 올바르게 인코딩 ksh93
할 수 있지만 ASCII가 아닌 문자의 경우 iso8859-1 문자 집합을 사용하는 로케일에서만 올바르게 작동합니다. 지원되지 않지만 작동합니다 .%H
%s
printf
&
&
ksh93
printf
-v
expanded_VAR1=${ printf... ;}
/ 메소드를 사용하면 printf
템플릿의 리터럴 문자를 zformat
이스케이프할 수 있고(다음과 같이) / +here-doc 메소드를 사용하면 / / 접두사를 붙여 이스케이프할 수 있습니다. 그러면 AFAIK, 탈출구가 없습니다.%
%%
\
\\
printf
e
eval
$
`
\
\
envsubst
$
답변2
매개변수 확장을 사용하여 var1의 고유 문자열을 var2의 값으로 바꿀 수 있습니다.
var1='<tr>
<th>unique_placeholder_var2</th>
</tr>'
var2=test
echo "${var1/unique_placeholder_var2/"$var2"}"
답변3
var1
올바른 형식의 XML이 포함되어 있다고 가정합니다 .
var1='
<tr>
<th>$var2</th>
</tr>
'
var2=test
xmlstarlet
그런 다음 모든 노드의 값을 th
다음과 같이 쉘 변수의 값으로 리터럴 값으로 바꿀 수 있습니다 .$var2
var2
var1=$( printf '%s\n' "$var1" | xmlstarlet ed -u '//th[text() = "$var2"]' -v "$var2" )
이는 수정하려는 모든 노드를 xmlstarlet
선택하기 위해 XPATH 쿼리를 호출합니다 . 이 노드의 값은 쉘 변수의 값으로 대체되고 결과는 표준 출력에 기록됩니다.th
xmlstarlet
var2
$ printf '%s\n' "$var1"
<?xml version="1.0"?>
<tr>
<th>test</th>
</tr>
이는 var2
XML 문서에 포함할 값을 올바르게 인코딩합니다.
$ var1='
<tr>
<th>$var2</th>
</tr>
'
$ var2='HÉLLO :->'
$ var1=$( printf '%s\n' "$var1" | xmlstarlet ed -u '//th[text() = "$var2"]' -v "$var2" )
$ printf '%s\n' "$var1"
<?xml version="1.0"?>
<tr>
<th>HÉLLO :-></th>
</tr>
답변4
템플릿에서 변수를 바꾸는 일반적인 방법:
- bash 정규식을 사용하여 변수 이름을 캡처합니다(탐욕적 일치로 인해 여기에서는 변수 이름이 오른쪽에서 왼쪽으로 일치됩니다).
- 변수를 사용하여 간접적으로 변수 값 얻기
- 무한 루프를 방지하려면 입력 문자열에서 일치하는 varname을 제거하세요(이렇게 하면 원래 문자열이 손상되므로 추가로 필요한 경우 백업하세요).
데모
대체할 템플릿과 (전부는 아님) 변수를 설정합니다.
VAR1="<tr> <th>\$VAR2</th> <th>\$VAR3</th> </tr>" VAR2=test unset VAR3
교체 수행
result="" while [[ $VAR1 =~ (.*)\$([[:alpha:]_][[:alnum:]_]*)(.*) ]]; do varname=${BASH_REMATCH[2]} [[ -v $varname ]] && replacement=${!varname} || replacement="\$${varname}" result="${replacement}${BASH_REMATCH[3]}${result}" VAR1=${BASH_REMATCH[1]} done result="${VAR1}${result}" declare -p result
검사 결과
declare -- result="<tr> <th>test</th> <th>\$VAR3</th> </tr>"
이를 위해서는 -v
운영자가 bash 버전 4.3+을 사용해야 합니다.