어딘가에 여러 줄 문자열에 대한 템플릿을 갖고 싶다고 가정해 보겠습니다.
I have some
text with ${placeholders}
in this and some ${different}
ones ${here} and ${there}
자리 표시자를 사용자 입력으로 바꾸는 가장 좋은 방법은 무엇입니까? 여기에 있는 문서가 유용합니까?
답변1
\<newline> 또는 문자 , , 또는 가 [a] 여러 줄 문자열 에 사용되지 않거나 올바르게 인용되었다고 가정하면 이 문서(및 변수)가 최선의 선택입니다.\
$
`
#!/bin/sh
placeholders="value one"
different="value two"
here="value three"
there="value four"
cat <<-_EOT_
I have some
text with ${placeholders}
in this and some ${different}
ones ${here} and ${there}.
_EOT_
실행되는 경우:
$ sh ./script
I have some
text with value one
in this and some value two
ones value three and value four.
물론 qouting을 올바르게 사용하면 변수도 작동합니다.
$ multilinevar='I have some
> text with '"${placeholders}"'
> in this and some '"${different}"'
> ones '"${here}"' and '"${there}"'.'
$ echo "$multilinevar"
I have some
text with value one
in this and some value two
ones value three and value four.
두 솔루션 모두 여러 줄의 변수 자리 표시자를 허용할 수 있습니다.
[a] 매뉴얼에서:
...문자 시퀀스 \<newline>은 무시되며 \는 \, $ 및 ` 문자를 인용하는 데 사용해야 합니다. ...
답변2
bash에서 이를 수행하는 한 가지 방법이 있습니다. 여기서는 연관 배열을 사용하므로 최신 버전이 필요합니다.
template=$(cat << 'END_TEMPLATE'
I have some
text with ${placeholders}
in this and some ${different}
ones ${here} and ${there}
END_TEMPLATE
)
mapfile -t placeholders < <(grep -Po '(?<=\$\{).+?(?=\})' <<< "$template" | sort -u)
declare -A data
for key in "${placeholders[@]}"; do
read -p "Enter the '$key' value: " -r data[$key]
done
t=$template
while [[ $t =~ '${'([[:alnum:]_]+)'}' ]]; do
t=${t//"${BASH_REMATCH[0]}"/"${data[${BASH_REMATCH[1]}]}"}
# ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# | + the value the user entered
# + the placeholder in the text
done
echo "$t"
답변3
사용자 입력이 주어지면 one
, two
,three
다음 명령은 ${placeholder}
제공된 모든 인스턴스를 입력으로 바꿉니다.
sed -i 's/${placeholders}/one/g; s/${different}/two/g; s/${here}/three/g' yourTemplateFile
이것을 bash 스크립트에서 사용하고 쉘 변수에 사용자 입력을 입력하면 하나의 명령으로 모든 대체가 수행됩니다.
답변4
다음 스크립트를 사용하여 테스트했으며 정상적으로 작동했습니다.
echo "enter count of userinput required"
read c
for ((i=1;i<=$c;i++))
do
echo "enter the values"
read input_$i
done
awk -v i="$input_1" -v j="$input_2" -v k="$input_3" -v l="$input_4" '{gsub(/\${placeholders}/,i,$0);gsub(/\${different}/,j,$0);gsub(/\${here}/,k,$0);gsub(/\${there}/,l,$0);print $0}' filename >>filename_tmp && mv filename_tmp filename