sed의 대체 항목 내에서 캡처된 표현식 평가

sed의 대체 항목 내에서 캡처된 표현식 평가

배포 스크립트를 개발 중이며 구성 파일에서 데이터베이스(또는 다른 시스템) 자격 증명을 교체해야 합니다.

다음과 같은 자격 증명이 포함된 PHP 파일이 있습니다.

<?php

return [
    'mysql-rw' => [
      'dns' => 'mysql-rw.local',
      'user' => 'local',
      'password' => 'PASS__LABELONE__',
    ],
    'mysql-ro' => [
      'dns' => 'mysql-ro.local',
      'user' => 'local',
      'password' => 'PASS__LABELTWO__',
    ],
];

LABELONE또한 CI 서버에 Bash 환경 변수가 설정되어 있습니다 . 파일의 템플릿을 한 줄 명령으로 바꾸고 LABELTWO싶지만 오류 또는 대체 오류가 있습니다.sed

LABELONE=pass1 LABELTWO=pass2 sed -r "s/PASS__(.+)__/${!\1}/" tst.txt 
bash: s/PASS__(.+)__/${!\1}/: bad substitution

내 접근 방식은 다음과 같습니다

  1. 파일에서 템플릿 찾기
  2. 태그를 캡처합니다(PASS__LBL__에서는 LBL입니다).
  3. 템플릿을 env로 바꿉니다. 변수($LBL)

그러한 동적 변수를 어떻게 평가할 수 있습니까 sed? 아니면 비현실적인 것입니까?

답변1

Perl은 %ENV 해시를 통해 env 변수에 액세스할 수 있습니다.

LABELONE=pass1 LABELTWO=pass2 perl -pe 's/PASS__(.+)__/$ENV{$1}/' -- tst.txt

답변2

(...)표현식에서 캡처된 그룹의 값은 sed동적으로 처리할 수 없습니다.세게 때리다GNU를 사용하는 환경 변수awk프로그램으로 변경:

export LABELONE="pass1"
export LABELTWO="pass2"

awk 'match($0, /PASS__([^_]+)__/, m){ sub(/PASS__[^_]+__/, ENVIRON[m[1]]) }1' testfile

산출:

<?php

return [
    'mysql-rw' => [
      'dns' => 'mysql-rw.local',
      'user' => 'local',
      'password' => 'pass1',
    ],
    'mysql-ro' => [
      'dns' => 'mysql-ro.local',
      'user' => 'local',
      'password' => 'pass2',
    ],
];

ENVIRON
환경 값을 포함하는 연관 배열입니다. 배열 인덱스는 환경 변수 이름이고 요소는 특정 환경 변수의 값입니다.

답변3

아마도 당신이 찾고 있는 것이 아닐 수도 있지만, 여러 sed를 통해 순차적으로 파이프하고 태그를 명시적으로 일치시키면 작동합니다... 확실히 우아하지는 않습니다.

LABELONE=pass1; LABELTWO=pass2;
sed -r "s/PASS__LABELONE__/$LABELONE/" tst.txt | sed -r "s/PASS__LABELTWO__/$LABELTWO/"

물론, 변수가 더 많거나 다른 이름으로 지정되면 금방 지루해질 수 있습니다. 아마도 bash 자체에서 뭔가를 할 수 있을 것입니다. 하지만 불행히도 저는 sed의 한 줄에서 그것을 수행하는 방법을 모릅니다.

편집: 음, 이러한 변수가 실제로 환경 변수이고 envsubst에 액세스할 수 있다고 가정하면 작동합니다.

내보내기LABLEONE=pass1

내보내기LABELTWO=pass2

sed -r "s/PASS__(.+)__/$\1/g" test.txt | sed -r "s/PASS__(.+)__/$\1/g" test.txt |환경 교체

그러나 이는 gettext의 일부인 envsubst에 의존합니다. 이것이 당신에게 적합한지 확실하지 않습니까? 또는 sed를 완전히 제거하고 구성 파일에 실제 $LABELONE 변수를 작성하여 envsubst를 사용할 수도 있습니다. 개인적으로 다른 댓글에 언급된 perl 스크립트가 마음에 들어서 투표했습니다.

관련 정보