그래서 일부 변수를 정의하기 위해 속성 파일을 로드합니다. 이 예에서는 mark!slash\ending\
이름이 문자열 이라고 가정합니다 INPUT
.
INPUT
다음을 사용하여 속성 파일을 로드하여 선언됩니다.
. ./properties
어디
INPUT=mark!slash\ending\
최종 출력은 SED를 통해 실행되는 스크립트여야 합니다. s!@output@!$INPUT!g
그러면 실행 시 @output@
사용자 정의 속성 파일의 입력이 다른 파일(이 경우 변수 INPUT
)로 대체됩니다. SED에서는 구분 기호를 사용하므로 !
SED 템플릿 파일에 추가하기 전에 이 문자(및 모든 문자)를 이스케이프해야 합니다.\
내가 시도하면
echo SAFE_INPUT=$(printf '%s\n' 'mark!slash\ending\' | sed 's:[\!]:\\&:g')
예상한 결과를 얻었습니다.
mark\!slash\\ending\\
그러나 내가 시도하면
SAFE_INPUT=$(printf '%s\n' "${INPUT}" | sed 's:[\!]:\\&:g')
알겠어요
mark\!slashending
나는 이것이 문자열 대 변수 선언과 관련이 있다고 가정하고 있지만 지금은 차이점과 문제를 해결하는 방법을 모릅니다.
편집: 추가 테스트에 INPUT
사용됨
. ./properties
다음으로 인쇄
mark!slashending
따라서 이는 SED의 문제가 아니라 속성 파일을 읽는 데 문제가 있는 것입니다.
답변1
문제는 질문에 표시된 것처럼 INPUT
파일에 변수를 설정할 때입니다.properties
INPUT=mark!slash\ending\
쉘 스크립트로 얻으십시오.
첫 번째 줄 뒤에 공백이 있으면 줄 끝의 \e
셸로 대체 e
됩니다 . 그렇지 않으면 줄이 다음 줄에서 계속된다는 의미입니다. \
그래서 값이 INPUT
수정되었습니다.
따옴표로 입력을 정의해야 합니다.
INPUT='mark!slash\ending\'
properties
Cornholio의 답변처럼 그렇지 않으면 파일을 다르게 구문 분석 해야 합니다 .
다음 명령을 사용하면 INPUT 변수(및 에 추가 행이 있는 경우 다른 변수 properties
)를 올바른 값으로 설정합니다.
eval $(sed -e 's:[\!]:\\&:g' properties)
그러면 및 및 의 내용을 대체하는 eval
uate 명령의 출력이 쉘에 제공됩니다 . 결과는 원래 이름 등을 가진 변수가 됩니다. 파일에 하나 이상의 변수 할당이 포함된 경우 작동합니다. 다른 쉘 스크립트 코드의 경우 이상한 결과가 나타날 수 있습니다.sed
\
!
properties
INPUT
properties
노트:입력 파일에 다른 특수 문자가 포함되어 있으면 처리가 더 어려워집니다. 따라서 별도의 확인 없이 사용하는 것은 eval
취약하거나 위험할 수 있습니다.
귀하의 예에 따르면 변수는 INPUT
예상 값을 갖습니다.mark!slash\ending\
그 후에는 할 수 있습니다
SAFE_INPUT=$(printf '%s\n' "${INPUT}" | sed 's:[\!]:\\&:g')
SAVE_INPUT
포함할 변수가 필요한 경우 mark\!slash\\ending\\
.
더 나은 접근 방식은 입력을 한 줄씩 읽고 줄을 while read -r line
검사하고 처리하여 변수 이름과 값을 분리하는 것입니다.
답변2
인용된 값으로 다음을 수행하면 INPUT
작동합니다.
> INPUT='mark!slash\ending\'
> SAFE_INPUT=$(printf '%s\n' "${INPUT}" | sed 's:[\!]:\\&:g')
> echo $SAFE_INPUT
mark\!slash\\ending\\
INPUT=
이것은 제가 추가한 내용이 포함된 스크립트의 정확한 사본입니다 .