sed: 문자열을 변수 내용으로 교체

sed: 문자열을 변수 내용으로 교체

{?varname}특정 패턴( )의 문자열을 찾아 해당 환경 변수로 바꾸는 스크립트를 작성하려고 합니다 .

이것이 내가 지금까지 가지고 있는 것입니다:

function get_env() {
   var=$1
   echo ${!var}
}

sed -e 's/{?\([a-z]*}\)/'$(get_env '\1')'/g' file.txt

이 함수는 다음과 같이 작동합니다 get_env LOGNAME-->dotan

echo __$1__sed는 함수의 값을 반환합니다. 예를 들어 함수의 내용을 I will get 으로 바꾸면 {?logname}-->__LOGNAME__

그러나 결합하면 작동하지 않습니다. 이는 함수가 항상 빈 문자열을 반환하는 것과 같습니다.

여기서 문제의 원인이 무엇인지 잘 모르겠습니다. 어떤 아이디어가 있나요?

답변1

명령줄은 get_env '\1'명령 대체에서 실행되며 해당 출력은 에 붙여넣어집니다 . 변수의 유효한 이름이 아니므 sed로 오류가 발생할 수 있습니다 .\1

s/\{\?([a-z]+)\}/$ENV{$1}/Perl을 사용하여 이를 수행 할 수 있습니다 . %ENV이는 환경 변수를 포함하는 해시입니다.

$ export name=you
$ echo "hello {?name}" | perl -pe 's/\{\?([a-z]+)\}/$ENV{$1}/'
hello you

(GNU sed에는 e외부 프로그램을 실행하는 명령이 있지만 일치하는 부분만이 아닌 전체 패턴 공간을 실행하기 때문에 여기에는 적합하지 않은 것 같습니다.)


순전히 Bash에서 ( )를 주장한다면 setvar.sh:

#!/bin/bash
while IFS= read -r line ; do
        while [[ $line =~ ^(.*)(\{\?[a-zA-Z0-9_]+\})(.*)$ ]] ; do
                varname=${BASH_REMATCH[2]}
                varname=${varname#"{?"}
                varname=${varname%\}}
                printf -v line "%s%s%s" "${BASH_REMATCH[1]}" "${!varname}" "${BASH_REMATCH[3]}"
        done
        printf "%s\n" "$line" 
done < "${1-/dev/stdin}"

$ echo 'foo {?BASH_VERSION} {?blah} bar' |blah=ABC bash setvar.sh
foo 4.4.12(1)-release ABC bar

답변2

이것이 내가 생각해낸 해결책이다

grep -o '{?\S*}' file.txt | sed 's/{?\(.*\)}/\1/' | xargs -I {} sh -c "sed -i -e 's/{?"{}"}/'$"{}"'/' file.txt"

그것을 파괴:

  • grep -o '{?\S*}' file.txt- 대체할 모든 변수를 가져옵니다.
  • sed 's/{?\(.*\)}/\1/'- 형식 제거
  • xargs -I {} sh -c "sed -i -e 's/{?"{}"}/'$"{}"'/' file.txt"- 각 변수를 개별적으로 검색하고 교체

관련 정보