sed/awk를 사용하여 YAML 파일 콘텐츠 필터링

sed/awk를 사용하여 YAML 파일 콘텐츠 필터링

다음 내용이 포함된 텍스트 파일이 있습니다.

$ cat hosts.yml
[prod_env]
foo.example.com
bar.example.com
[stage_env]
foo_stage.example.com
bar_stage.example.com
[dev_env]
foo_dev1.example.com
dev2_bar.example.com

Bash의 [prod_env] 파일 아래에 나열된 호스트를 필터링하고 싶습니다. 제한된 지식으로 sed, awk 및 grep을 시도했지만 필터링하는 방법을 모르겠습니다.

예: prod_env 및 dev_env 아래의 호스트를 인쇄하고 싶습니다. 따라서 최종 출력은 다음과 같습니다.

foo.example.com 
bar.example.com 
foo_dev1.example.com 
dev2_bar.example.com

답변1

해결책 sed:

sed -nEe '/\[(prod|dev)_env]/!d;N;:loop' -e 's/.*\n//;${p;d;};N;P;/\n\[/D;bloop' hosts.yml
  • /\[(prod|dev)_env]/!d[prod_env]찾 거나 [dev_env]찾을 때까지 모든 행 삭제
  • N;:loop다음 줄을 추가하고 반복 시작
  • 루프 내에서 두 줄 중 첫 번째 줄을 삭제합니다. s/.*\n//해당 [...env]줄이거나 마지막 루프 주기에서 이미 인쇄했기 때문입니다.
  • ${p;d;}인쇄하는 동안 마지막 줄에 도달하면 나머지 줄을 인쇄합니다.
  • N;P다음 줄 추가 및 현재 줄 인쇄
  • /\n\[/D다음 줄이 로 시작하는지 확인하세요 [. 이 경우 버퍼의 첫 번째 줄(인쇄된)을 삭제할 수 있으며 [해당 줄부터 시작합니다.
  • bloop그렇지 않으면 루프

버퍼에 다음 줄을 추가하고 이전 줄을 인쇄하고 삭제하는 대신 한 줄씩 수행할 수 있지만 다시 시작할 수 없기 때문에 또 다른 루프가 필요합니다.D

답변2

(Mac에서) 다음을 수행할 수 있습니다.

tr "\n" "\t" < hosts.yml | sed $'s%\t\\[%\\\n\[%g' | grep 'prod\|dev' | sed $'s%.*\]\\\t%%g' | tr "\t" "\n"
  1. tr모든 것을 한 줄에 넣을 것입니다
  2. 첫 번째 항목은 sed각 섹션 전에 래핑됩니다.
  3. grep원하는 선(부분)을 잘라드립니다.
  4. 두 번째로 sed[] 부분이 제거됩니다.
  5. tr각 줄이 하나의 호스트 이름을 갖도록 줄 이 끝에서 줄바꿈됩니다.

답변3

awk 'BEGIN{RS="[";FS="]\n"} 
     $1 ~/(prod|dev)_env/ {print $2}' ex1

답변4

GNU sed아래 표시된 방법을 사용하여 이 작업을 수행 할 수 있습니다 .

$ sed -nEe '
   /\[/!{H;$!d;}
   x;1!s/^\[(prod|dev)_env]\n//p
' hosts.yml

관련 정보