awk를 간단한 템플릿 엔진으로 사용하여 getline의 마지막 줄 출력을 수정하는 방법

awk를 간단한 템플릿 엔진으로 사용하여 getline의 마지막 줄 출력을 수정하는 방법

저는 awk를 사용하여 몇 가지 간단한 템플릿을 작성하려고 합니다. 다음과 같은 "템플릿" 파일이 있습니다.

{
  "Thing": {
    "Code": [
      #include_code
    ]
  }
}

다음 awk 프로그램을 사용하여 #include_code행을 파일의 내용으로 바꾸었지만 각 행을 큰따옴표로 묶고 쉼표로 끝냈습니다(출력에 유효한 JSON 목록을 생성하기 위해).

#!/usr/bin/awk -f

! /#include_code/ { print $0 }

/#include_code/ {
  while(( getline line<"test_file.js") > 0 ) {
    print "\"" line "\","
  }
}

어디 test_file.js:

index.handler = (event, context) => {
    return true;
}

내 문제는 마지막 쉼표가 인쇄되는 것을 원하지 않지만 해당 쉼표가 인쇄되는 것을 방지하는 방법을 잘 모르겠습니다. 명확하게 말하면 다음과 같은 결과가 나옵니다.

{
  "Thing": {
    "Code": [
"index.handler = (event, context) => {",
"    return true;",
"}", <--- I don't want this comma...
    ]
  }
}

awk를 사용하여 이 작업을 수행하는 것에 대한 답변을 원하지만(배우려고 하기 때문에). 귀하가 제게 사용하라고 제안한 다른 템플릿 도구를 알려 주는 답변을 받게 되어 기쁩니다.

답변1

한 가지 방법은 스크립트 시작 부분의 줄 수를 세는 것입니다. 출력시 줄번호와 줄수가 일치하지 않는 경우에만 마지막에 쉼표를 출력하세요. 이를 수행하는 방법을 설명합니다.여기.

또 다른 방법은 첫 번째 항목을 출력할 때 쉼표를 인쇄하는 대신앞으로후속 항목. 이 작업은 다음과 같이 수행할 수 있습니다.

 awk -F, '{if (!i)printf "\""$0"\"";else printf ",\n\""$0"\"";i=1}END{print ""}' a.in

확실히 훨씬 깔끔해졌네요.

세 번째 방법이 있습니다. 암호

 if(getline == 0)

파일의 끝에 있는지 여부를 알려주는 다음 줄을 읽습니다. 이는 위의 방법보다 깔끔하지만 파일을 효과적으로 두 번 읽는 오버헤드가 발생하므로 두 번째 방법이 실패하지 않는 한 이 방법을 사용하지 않을 것입니다(예: 끝에서 두 번째 방법도 다르게 처리해야 합니다. OK).

답변2

이렇게 하는 것이 더 쉬울 수도 있습니다.

sed 's/.*/"&"/;$!s/$/,/' test_file.js | sed '/#include_code/{
  r /dev/stdin
  d;}' template

(한 번만 나타난다고 가정 #include_code).

를 사용하면 awk다음을 수행할 수 있습니다.

awk '
  /#include_code/ {
    sep = ""
    while((getline < "test_file.js") > 0) {
      printf "%s", sep "\"" $0 "\""
      sep = ",\n"
    }
    if (sep) print ""
    next
  }
  {print}' template

sed위와 유사한 접근 방식을 사용할 수도 있습니다 .

CODE='test_file.js' SED='sed '\''s/.*/"&"/;$!s/$/,/'\' "$CODE"' awk '
  /#include_code/{system(ENVIRON["SED"); next};{print}' template

관련 정보