이전 줄에 특정 단어가 포함된 경우에만 줄을 인쇄합니다.

이전 줄에 특정 단어가 포함된 경우에만 줄을 인쇄합니다.

호스트 이름과 호스트 IP가 포함된 다음 파일이 있습니다(긴 파일, Linux 상자당 90-100개의 머신).

hosts.cluster.conf

  "href" : "http://localhost:8080/api/v1/hosts/worker02.sys87.com",
  "Hosts" : 
    "cluster_name" : "hdp",
    "host_name" : "worker02.sys87.com",
    "ip" : "23.67.32.65"


  "href" : "http://localhost:8080/api/v1/hosts/worker03.sys87.com",
  "Hosts" : 
    "cluster_name" : "hdp",
    "host_name" : "worker03.sys87.com",
    "ip" : "23.67.32.66"


  "href" : "http://localhost:8080/api/v1/hosts/worker04.sys87.com",
  "Hosts" : 
    "host_name" : "worker04.sys87.com",
    "ip" : "23.67.32.67"


  "href" : "http://localhost:8080/api/v1/hosts/worker05.sys87.com",
  "Hosts" : 
    "cluster_name" : "hdp",
    "host_name" : "worker05.sys87.com",
    "ip" : "23.67.32.68"

모두 인쇄하고 싶습니다.CPU 이름이전 줄에 "가 포함된 경우에만클러스터 이름" 단어

기대되는 성과

"host_name" : "worker02.sys87.com",

"host_name" : "worker03.sys87.com",

"host_name" : "worker05.sys87.com",

답변1

sed '/host_name/!h;//!d;x;/cluster_name/!d;g' infile

host_name이전 버퍼와 일치하지 않는 모든 라인을 저장 h한 다음 d남은 모든 라인에 대해 삭제합니다. x버퍼를 변경하고 패턴 공간에 해당 라인이 없으면 cluster_name삭제합니다. 그렇지 않으면 g버퍼에서 저장하고 자동으로 인쇄합니다. 원래 행을 반환합니다.

답변2

노력하다

 awk '/cluster_name/ {p=1 ; next ;} 
 /host_name/ && p { print ; }
 {p=0}' 

기본적으로 이것만 기억하세요 cluster_name. host_name발견되었지만 이전에 발견되지 않은 경우 cluster_name인쇄되지 않습니다.

전체 awk 코드는 한 줄이 될 수 있습니다.

답변3

짧은awk해결책:

awk '/cluster_name/{ cl=NR }/host_name/ && NR-1==cl' hosts.cluster.conf
  • /cluster_name/{ cl=NR }- "cluster_name"레코드 행 수 캡처
  • /host_name/- 만남의 "host_name"선 에서
  • NR-1==cl- 현재 "host_name"레코드 번호 가 레코드 번호 다음( 으로 표시 ) NR인지 확인하세요."cluster_name"cl

산출:

"host_name" : "worker02.sys87.com",
"host_name" : "worker03.sys87.com",
"host_name" : "worker05.sys87.com",

첫 번째 줄에 나타나면 host_name실제로 그럴지는 의심스러우나 다음 버전을 사용하세요.

awk '/cluster_name/{ cl=NR }/host_name/ && cl && NR-1==cl' hosts.cluster.conf

답변4

자, 여기까지 왔습니다 sed. awk이제 GNU를 사용할 시간입니다 grep!

cat infile | grep --after-context 1 cluster_name | grep host_name

설명하다

첫 번째 명령은 cat처리를 위해 데이터를 파이프로 읽어옵니다. 이 단락을 소스 텍스트를 에 출력하는 명령으로 바꿀 수 있습니다 stdout.

두 번째 명령은 "cluster_name"이 포함된 줄을 찾아 해당 줄과 다음 줄을 인쇄합니다. 중간 출력은 다음과 같습니다.

"cluster_name" : "hdp",
"host_name" : "worker02.sys87.com",
--
"cluster_name" : "hdp",
"host_name" : "worker03.sys87.com",
--
"cluster_name" : "hdp",
"host_name" : "worker05.sys87.com",

그런 다음 마지막 단락에서는 "host_name"이 포함된 줄의 내용만 인쇄합니다. 따라서 최종 출력은 다음과 같습니다.

"host_name" : "worker02.sys87.com",
"host_name" : "worker03.sys87.com",
"host_name" : "worker05.sys87.com",

논평

  1. grep모든 사람이 "GNU grep을 사용하고 있는지 확인"하는 것은 아니며 --before-context parameter.괜찮을 것입니다.
  2. 이것이 JSON과 같은 언어라면 jmespath 또는 jq.

관련 정보