특수 문자({ & }) 사이에 패턴 일치가 발생해야 하는 경우 특수 문자 사이에 데이터를 인쇄하려면 Sed/awk 명령이 필요합니다.
다음이 포함된 파일이 있습니다.
define service {
host_name dns_vips
service_description Multi Lookup
use standard_service_template
active_checks_enabled 1
passive_checks_enabled 1
notifications_enabled 1
contact_groups mailgrp
max_check_attempts 3
normal_check_interval 5
retry_check_interval 1
notification_interval 10
check_period 24x7
notification_period 24x7
notification_options w,r,c
}
define service {
host_name dns_vips1
service_description Multi Lookup 2
use standard_service_template
active_checks_enabled 1
passive_checks_enabled 1
notifications_enabled 1
contact_groups mailgrp1
max_check_attempts 3
normal_check_interval 5
retry_check_interval 1
notification_interval 10
check_period 24x7
notification_period 24x7
notification_options w,r,c
}
{
다중조회를 통해 기간 및 기간 데이터를 매칭하기 위한 서비스 설명이 필요합니다.}
답변1
sed '
/{/{ #starts next code block if line include «{»
:1 #set mark point
/}/!{ #execute if pattern (collected lines) do not include «}»
N #add next line to the pattern space
b1 #return to marked point
} #end of second (inner) block of code
} #end of first block of code
/Multi Lookup/p #prints pattern (collected lines) if it has «Multi Lookup»
d #clean pattern (start from the beginning)
' file
답변2
제가 올바르게 이해했다면 귀하의 모든 데이터가 거기에 있으며 { }
귀하 service_description
는 Multi Lookup
. 그렇다면 perl
사용할 수 있는 멋진 트릭이 있습니다.
Perl에는 레코드(줄)가 빈 줄로 정의되는 "단락 모드"가 있습니다. 따라서 매 뒤에 개행 문자를 추가하면 }
간단하게 다음과 같이 할 수 있습니다.
sed 's/}/}\n/' file | perl -00ne '/service_description\s*Multi Lookup/ && print'
sed
Perl은 단락 모드를 켜고 각 입력 줄(여기서 줄은 단락을 의미함)을 읽고 주어진 스크립트를 적용합니다 . 결과는 일치하는 레코드를 인쇄하는 것입니다.\n
}
-00
-ne
-e
service_description
Multi Lookup
$/
또는 Perl의 레코드 구분 기호("라인"이 무엇인지 정의), 스크립트 자체의 변수를 설정하고 해당 sed
단계를 피할 수 있습니다.
perl -ne 'BEGIN{$/="}\n"}/service_description\s*Multi Lookup/ && print' file
답변3
그냥 재미 vim
삼아 선으로 해보았습니다. (누가 그런 얘기를 들어본 적 있잖아요?)
vim -c 'g/service_description\s\+Multi Lookup\s\+$/?{?+,/}/-w! >> outputfile.txt' -c 'q!' inputfile.txt
기능: service_description
[공백] [공백, 줄 끝]을 포함하는 각 줄을 찾아 및 문자를 포함하는 줄을 제외하고 Multi Lookup
각 일치 항목의 앞에서 뒤로 모든 줄을 출력하고 출력 줄을 작성합니다. 그런 다음 수정 없이 종료됩니다.{
}
{
}
outputfile.txt
inputfile.txt
일치 시키고 싶은지 모르겠습니다 Multi Lookup 2
. 그렇다면 \s\+$
다음을 제거하세요 Multi Lookup
.
중괄호가 있는 줄도 포함하려면 +
다음 ?{?
및 -
다음 을 제거하세요 /}/
.
그냥 사용할 수 있기 때문에 약간 과잉일 수도 있지만 sed
나에게는 좋은 연습이었습니다. :)
답변4
사용행복하다(이전 Perl_6)
~$ raku -e '.put if /service_description \h+ Multi \h Lookup/ for slurp.comb(/^^ define \h service \h \{ <-[ } ]>* \} $$ /);' file
#OR (more simply)
~$ raku -e '.put if /DESIRED_MATCH/ for slurp.comb( / ^^START <-[ END_char ]>* END$$ /);'
위 내용은 Perl 계열의 프로그래밍 언어인 Raku로 작성된 답변입니다. 코드를 오른쪽에서 왼쪽으로 읽는 Raku는 slurp
한 번에 파일을 메모리로 읽어 들이고 그 comb
반대의 경우도 가능합니다.split
선택하다동일한 텍스트 블록을 삭제하는 대신 텍스트 블록을 일치시키는 데 사용됩니다. 이 접근 방식을 사용하면 원하는 텍스트 블록 사이에 불필요한 문자가 있는지 선택이 구분되지 않습니다.
^^
줄 시작 및 $$
줄 끝 어설션은 구체성을 제공하는 데 사용되며 블록 내부 문자 사용은 닫는 중괄호를 제외한 모든 문자 <-[ } ]>*
(0개 이상)를 포함하는 음수 문자 클래스인 정의됩니다. ed 요소에 대한 반복을 사용하여 원하는 일치 항목( 가로 공백을 나타냄)을 찾으면 해당 요소가 나옵니다 .}
comb
for
if
\h
put
OP의 입력 파일(네거티브 제어를 제공하기 위해 두 번째 컬 블록 변경)이 주어지면 다음과 같은 출력을 얻습니다.
입력 예:
define service {
host_name dns_vips
service_description Multi Lookup
use standard_service_template
active_checks_enabled 1
passive_checks_enabled 1
notifications_enabled 1
contact_groups mailgrp
max_check_attempts 3
normal_check_interval 5
retry_check_interval 1
notification_interval 10
check_period 24x7
notification_period 24x7
notification_options w,r,c
}
define service {
host_name dns_vips1
service_description Single Lookup
use standard_service_template
active_checks_enabled 1
passive_checks_enabled 1
notifications_enabled 1
contact_groups mailgrp1
max_check_attempts 3
normal_check_interval 5
retry_check_interval 1
notification_interval 10
check_period 24x7
notification_period 24x7
notification_options w,r,c
}
예제 출력:
define service {
host_name dns_vips
service_description Multi Lookup
use standard_service_template
active_checks_enabled 1
passive_checks_enabled 1
notifications_enabled 1
contact_groups mailgrp
max_check_attempts 3
normal_check_interval 5
retry_check_interval 1
notification_interval 10
check_period 24x7
notification_period 24x7
notification_options w,r,c
}
사용된 검색 정규식을 단순화하기 위해 comb
Raku의 ~
물결표 표기법을 사용하여 대안을 제공하는 일치하는 구분 기호(중괄호, 대괄호, 대괄호 등)를 찾을 수 있습니다 [ \{ ~ \} <-[ } ]>* ]
. 또한 Raku의 slurp
ed 데이터 의 내부 표현을 보려면 다음과 같이 if
조건을 제거하고 사용하십시오 .raku.put
.
~$ raku -e '.raku.put for slurp.comb(/^^ define \h service \h [ \{ ~ \} <-[ } ]>* ] $$/);' file
"define service \{\nhost_name dns_vips\nservice_description Multi Lookup \nuse standard_service_template\nactive_checks_enabled 1\npassive_checks_enabled 1\nnotifications_enabled 1\ncontact_groups mailgrp\nmax_check_attempts 3\nnormal_check_interval 5\nretry_check_interval 1\nnotification_interval 10\ncheck_period 24x7\nnotification_period 24x7\nnotification_options w,r,c\n}"
"define service \{\nhost_name dns_vips1\nservice_description Single Lookup\nuse standard_service_template\nactive_checks_enabled 1\npassive_checks_enabled 1\nnotifications_enabled 1\ncontact_groups mailgrp1\nmax_check_attempts 3\nnormal_check_interval 5\nretry_check_interval 1\nnotification_interval 10\ncheck_period 24x7\nnotification_period 24x7\nnotification_options w,r,c\n}"
slurp
파일을 한꺼번에 가져오는 데 문제가 있는 경우 lines.join("\n")
다음을 시도해 보세요.가능한메모리 효율성을 향상시킵니다. 또한 이 답변은 Raku의 해시 데이터 구조를 사용하여 다시 작성할 수 있으므로 %
여러 가지 키-값 쌍을 더욱 효율적으로 분석할 수 있습니다.
https://docs.raku.org/언어/regexes#Tilde_for_nesting_structs
https://docs.raku.org
https://raku.org