다음 구성 파일이 있습니다.
define host{
host_name xxxxxxxx1748
use windows-server
alias Comet
hostgroups +bu-automotiveprd,screen-automotiveprd2
address XXX.XXX.XXX.XXX
}
define host{
host_name yyyyyyyyy991
use aix-server
alias
hostgroups +bu-automotiveprd,screen-automotiveprd2
address YYY.YYY.YYY.YYY
}
검색하고 싶어요CPU 이름, 일치하는 항목이 있으면 출력은 다음과 같아야 합니다.
yyyyyyyyy991
예 - 호스트를 검색하고 싶다고 가정해 보겠습니다 .
그러면 출력은 다음과 같아야 합니다.
define host{
host_name yyyyyyyyy991
use aix-server
alias
hostgroups +bu-automotiveprd,screen-automotiveprd2
address YYY.YYY.YYY.YYY
}
답변1
이 시도,
perl -0777 -ne '/([^\n]*{[^}]*(yyyyyyyyy991)[^}]*})/ && print "$1\n"' file
설명하다:
perl -0777
Perl을 실행하고 전체 파일을 한 줄로 읽습니다.-ne
각 행(n
) 에 대해e
다음( ) 작업을 수행합니다./(pattern)/ && print "$1\n"
정규식 패턴을 일치시키고 이를 첫 번째 일치 그룹($1
)으로 추가한 다음 인쇄합니다.
모델:
[^\n]*{ ... }
"{"부터 다음 "}"까지를 포함하여 줄의 시작 부분부터 무엇이든 일치합니다.- 그리고
...
존재[^}]*(yyyyyyyyy991)[^}]*
:- 그렇지 않은 모든 문자와 일치합니다.
}
- 어딘가에 포함되어야 합니다
yyyyyyyyy991
.
- 그렇지 않은 모든 문자와 일치합니다.
답변2
지원 하는 경우 grep
이 -z
옵션을 사용하여 전체 파일을 먹도록 할 수 있습니다.
$ grep -ozE 'define[^}]*host_name yyyyyyyyy991.+?}.' file
define host{
host_name yyyyyyyyy991
use aix-server
alias
hostgroups +bu-automotiveprd,screen-automotiveprd2
address YYY.YYY.YYY.YYY
}
사용된 옵션은 다음과 같습니다( GNU 페이지 grep
에서 ):man
grep
-z, --null-data
Treat input and output data as sequences of lines, each terminated by a
zero byte (the ASCII NUL character) instead of a newline. Like the -Z or
--null option, this option can be used with commands like sort -z to
process arbitrary file names.
-o, --only-matching
Print only the matched (non-empty) parts of a matching line, with each
such part on a separate output line.
-E, --extended-regexp
Interpret PATTERN as an extended regular expression (ERE, see below).
정규식은 단어 define
뒤에 0개 이상의 비 }
문자( [^}]*
)가 오는 단어를 찾은 다음 첫 번째 ( )와 개행 문자 (마지막 문자) 와 일치하는 다음 문자 host_name yyyyyyyyy991
까지의 모든 항목을 찾습니다.}
.+?
.
그러나 개인적으로 나는 Perl의 단락 모드를 사용하여 다음과 같은 작업을 수행합니다.
$ perl -00 -ne 'print if /yyyyyyyyy991/' file
define host{
host_name yyyyyyyyy991
use aix-server
alias
hostgroups +bu-automotiveprd,screen-automotiveprd2
address YYY.YYY.YYY.YYY
}
입력 파일이 단락으로 읽혀지므로 각 레코드는 한 줄이 아닌 단락(2개의 연속 문자로 정의됨 -00
) 임을 나타냅니다 . 그러면 "각 입력 레코드를 읽고 주어진 스크립트를 여기에 적용한다 "는 의미입니다. 스크립트 자체는 원하는 패턴과 일치하는 모든 레코드를 간단히 인쇄합니다.perl
\n
-ne
-e
답변3
구성 파일의 이름이 config.dat이고 다음이 있다고 가정합니다.기준체재. 즉, yyyyyyyyy991 앞에는 한 줄만 있고 그 뒤에는 다섯 줄만 있습니다. 그러면 이 명령은 원하는 출력을 얻는 데 도움이 됩니다.
grep -B 1 -A 5 "yyyyyyyyy991" config.dat
define host{
host_name yyyyyyyyy991
use aix-server
alias
hostgroups +bu-automotiveprd,screen-automotiveprd2
address YYY.YYY.YYY.YYY
}
~에서grep
남성:
Context control flage:
-B, --before-context=NUM print NUM lines of leading context
-A, --after-context=NUM print NUM lines of trailing context
config.dat 파일이 다른 솔루션인 경우표준이 아님, 이는 키워드 "yyyyyyyyy991"이 모든 섹션에서 동일한 패턴을 따르지 않음을 의미하므로 awk
다음과 같이 원하는 작업을 수행할 수 있습니다.
awk -v RS='' '/host_name yyyyyyyyy991/' config.dat
RS=는 입력 레코드 구분 기호를 개행 문자에서 빈 줄로 변경합니다. 레코드의 필드에 /host_name yyyyyyyyy991/이 포함된 경우 레코드를 인쇄합니다.
RS가 비어 있는 경우 레코드는 하나 이상의 빈 줄 시퀀스로 구분됩니다. 선행 또는 후행 빈 줄은 입력의 시작이나 끝 부분에 빈 레코드가 되어서는 안 되며, a는 FS What에 관계없이 항상 필드 구분 기호여야 합니다. 값입니다.
출력 구분 기호는 여전히 단일 개행 문자이므로 출력 단락은 구분되지 않습니다. 출력 단락 사이에 빈 줄이 있는지 확인하려면 출력 레코드 구분 기호를 두 개의 줄 바꿈으로 설정하세요.
답변4
사용 sed
:
sed 'H;/^define host{$/h;/^}/{g;/host_name yyyyyyyyy991\n/p};d' file
단계별:
H # append line to hold space
/^define host{$/h # start of entry: copy to hold space (overwrites previous content)
/^}/{ # end of entry:
g # retrieve whole entry from hold space
/host_name yyyyyyyyy991\n/p # if host matched, display the whole entry
}
d # no other output