CPUNAME AGENT_1
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_2
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TIMEZONE abc
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_3
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
DOMAIN MASTERDM
*MANAGER AGENT_1
ISMASTER
END
위 파일에서 먼저 패턴 일치 "TYPE" 뒤에 "IGNORE" 줄을 추가했습니다.
sed -i '/^ TYPE.*/a IGNORE' filename
특정 CPU(예: AGENT_1 AGENT_3)에 대한 IGNORE 플래그를 제거해야 하지만 IGNORE 위치가 위에 표시된 대로 고정되어 있지 않습니다. 다른 블록의 숫자 8, 9, 6이 곧 출시될 예정입니다. 지금은 IGNORE 플래그가 위치 8에 있는 파일을 편집하고 있는 CPU를 알고 있으므로 루프를 사용하여
for
IGNORE를 제거합니다.for s in `cat $INPUT_FILE | awk '{print $1}'`; do echo $s sed -i "/$s/!b;n;n;n;n;n;n;n;d" Filename done
내가 아는 한, NODE 위치는 모든 블록에 대해 항상 고정되어 있으므로 다음 명령을 사용하여 라인을 교체했습니다.
for n in `cat $INPUT_FILE`; do CPU=$(echo $n | cut -f1) NODE=$(echo $n | cut -f2) echo "$CPU" echo "$NODE" sed -i "/$CPU/!b;n;n;n;c $NODE" filename done
위의 모든 내용은 특정 CPU에 대한 무시를 제거하는 것을 제외하고는 잘 작동합니다(고정 라인이 아닌 경우). 솔루션 개선을 위한 소중한 제안을 보내주세요.
답변1
작업: IGNORE
CPU 이름을 지정하는 줄 삭제
줄 을 제거하려면 IGNORE
다음을 사용할 수 있습니다.AGENT_1
AGENT_3
awk '$1 == "CPUNAME" && ($2 == "AGENT_1" || $2 == "AGENT_3") { x=1 }
/^END$/ { x=0 }
x && /^ *IGNORE$/ { next }
1' inputfile
필요에 따라 기준에서 CPU 이름을 추가하거나 제거할 수 있습니다.
그러면 수정된 데이터가 표준 출력으로 인쇄됩니다. 일반적으로 말해서, 문제가 발생하면 데이터가 손실될 수 있으므로 내부 편집을 권장하지 않습니다. 입력 파일을 내부 편집을 지원하지 않는 도구로 바꾸고 싶다면 언제든지 다음과 같은 것을 사용할 수 있습니다.
awk 'some script' inputfile > tempfile && mv tempfile inputfile
설명하다
$1 == "CPUNAME" && ($2 == "AGENT_1" || $2 == "AGENT_3")
첫 번째 필드가CPUNAME
지정된 이름 중 하나이고 두 번째 필드가 지정된 이름 중 하나이면 조건이 일치합니다.{ x=1 }
이 블록에서 제거하려는 항목을x
표시하는 플래그를 설정합니다.IGNORE
/^END$/ { x=0 }
전체 라인이 블록 끝에 있는 클리어 플래그와 일치하는 경우END
.x
x && /^ *IGNORE$/
플래그가 설정된 경우에만IGNORE
선행 공백이 있는 줄을 일치시키는 조건입니다 .x
{ next }
라인의 추가 처리를 건너뜁니다. 즉, 인쇄하지 않습니다.1
true
기본 작업이 없는 (= 행당) 조건 입니다print
. (예를 들어 와 같이 더 자세히 작성할 수 있습니다{ print }
.)
질문의 예시 입력을 사용하세요.
CPUNAME AGENT_1
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_2
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TIMEZONE abc
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_3
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
DOMAIN MASTERDM
*MANAGER AGENT_1
ISMASTER
END
출력은 다음과 같습니다
CPUNAME AGENT_1
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_2
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TIMEZONE abc
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_3
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
DOMAIN MASTERDM
*MANAGER AGENT_1
ISMASTER
END
반대 작업: IGNORE
행 삽입
실제 입력 파일에 IGNORE
줄이 없으면 지정된 CPU 이름과 일치하는(또는 일치하지 않는) 줄 뒤의 블록에만 줄을 삽입하는 스크립트를 사용할 수도 있습니다 TYPE
.
예: IGNORE
둘 중 하나도 일치하지 않는 블록을 삽입하고AGENT_1
AGENT_3
awk '$1 == "CPUNAME" && ($2 != "AGENT_1" && $2 != "AGENT_3") { x=1 }
/^END$/ { x=0 }
1
x && $1 == "TYPE" { print " IGNORE" }' inputfile
설명하다:(첫 번째 스크립트와만 다름)
$1 == "CPUNAME" && ($2 != "AGENT_1" && $2 != "AGENT_3")
첫 번째 필드CPUNAME
와 두 번째 필드에는 이름이 없습니다.x && $1 == "TYPE"
플래그가x
설정되고 첫 번째 필드는TYPE
{ print " IGNORE" }
라인 인쇄IGNORE
(TYPE
라인 뒤)
AGENT_1
CPU를 사용한 입력 예.. AGENT_4
및 줄 없음 IGNORE
:
CPUNAME AGENT_1
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_2
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TIMEZONE abc
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_3
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_4
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
DOMAIN MASTERDM
*MANAGER AGENT_1
ISMASTER
END
결과 출력:
CPUNAME AGENT_1
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_2
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TIMEZONE abc
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_3
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_4
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
DOMAIN MASTERDM
*MANAGER AGENT_1
ISMASTER
END
답변2
사용행복하다(이전 Perl_6)
~$ raku -e 'my @a = slurp.split("\n\n"); .subst(" IGNORE\n").put if .match(/AGENT_1 | AGENT_3/) for @a;' file
즉, 위의 코드는 Raku 프로그래밍 언어를 사용합니다. Use는 전체 파일을 읽고 slurp
이를 \n\n
연속 개행 문자로 레코드로 분할하여 배열에 저장합니다 @a
. 그런 다음 레코드가 match
필수 레코드 중 하나 인 경우 " " 행이 아무것도 대체되지 않은 상태 로 AGENT
레코드가 삭제됩니다 (예: 삭제됨).put
IGNORE\n