Bash/Sed/Awk를 사용하여 템플릿 파일에서 변수 이름을 찾으시겠습니까?

Bash/Sed/Awk를 사용하여 템플릿 파일에서 변수 이름을 찾으시겠습니까?

현재 훌륭하게 작동하는 envsubst를 사용하여 처리하고 있는 일부 템플릿 파일이 있습니다.

<?php

$config['db_host'] = '${DB_HOST}';
$config['db_port'] = '${DB_PORT}';
$config['url'] = 'http://${WEB_HOST}/${WEB_PATH}';

// Please do NOT change this value
$config['maxSize'] = 25;

bash 스크립트를 사용하여 파일을 스캔하고 설정해야 하는 모든 환경 변수 목록을 생성하여 다음과 같이 .env 파일에 덤프할 수 있는 방법을 찾으려고 합니다.

DB_HOST=
DB_PORT=
WEB_HOST=
WEB_PATH=

sed로 가능하다고 생각했는데, 30분 동안 구글링해서 찾은 예제는 모두 인라인 변수를 교체하는 방법에 관한 것이지 일치 항목을 인쇄하는 방법에 관한 것이 아니었습니다.

답변1

귀하의 기준은 다음과 같습니다: ${및 사이에 포함된 대문자 또는 밑줄 수와 일치합니다 }.

gawk이는 단독으로 사용할 수도 있고, grep패턴 매칭 부분을 단순화할 수도 있습니다(단, 이후 추가 서식이 필요함).


그누 awk:

gawk -v 'RS=[$]{' -F '}' '$1 ~ /^[A-Z_]+$/ && !a[$1]++ {printf "%s=\n", $1}' FILE
  • GNU awk는 레코드 구분 기호에 대한 정규식을 허용하므로 이를 할당하면 패턴이 발생할 때마다 RS=[$]{입력을 레코드로 분할합니다.FILE${
  • 필드 구분 기호가 다음으로 설정됨 }- 이제 각 레코드의 첫 번째 필드를 확인하여 다른 기준과 일치하는지 확인할 수 있습니다.[A-Z_]
  • 중복 항목은 다음을 사용하여 && !a[$1]++제거됩니다 .
  • =print 문은 원하는 출력과 일치하도록 각 줄 끝에 등호를 추가합니다.
  • 또한 참고: 파일의 첫 번째 부분은 시작하지 않더라도 항상 첫 번째 레코드로 계산됩니다. ${즉, 파일이 다음 [A-Z_]+}으로 시작하는 경우(가능성 없음) 이러한 대문자/밑줄은 "일치"되어 인쇄됩니다. 출력의 첫 번째 줄

grep+ 형식

grep-o/ 옵션 덕분에 이해하기 더 쉬울 수도 있습니다 --only-matching.

grep -o '${[A-Z_]\+}' FILE
  • 그러나 이는 출력 형식을 지정하지 않습니다. sed파이프를 통해 이를 수행할 수 있습니다.
grep -o '${[A-Z_]\+}' FILE | sed 's/${\(.*\)}/\1=/'
  • 중복 항목은 제거되지 않습니다. sort -u출력을 파이핑하거나 awk를 통해 한 번 파이핑하여 수행합니다.
grep -o '${[A-Z_]\+}' FILE | awk -F '[{}]' '!a[$0]++{printf "%s=\n", $2}'

답변2

이것이 내가 한 일입니다.

cat file | grep -o '${\w*}' | sed -e 's|${||g' -e 's|}|=|g'

DB_HOST=
DB_PORT=
WEB_HOST=
WEB_PATH=

예쁘진 않아도 꽤 잘 어울리는 것 같아요!

또는 다른 방법(에서 수정됨)https://unix.stackexchange.com/a/13467/229729):

cat file | sed -n -e 's/.*${\(\w\+\)}.*/\1=/p'

관련 정보