다음 텍스트가 포함된 파일을 검색하고 세 번째 줄에 "Msg 208" 뒤에 "# 이름을 찾을 수 없음"이 있는 출력만 리디렉션하려면 어떻게 해야 합니까?
파일 텍스트:
[
DBCC upgrade_object: DEFAULT dc_1527463 upgraded successfully.
DBCC upgrade_object: Upgrading PROCEDURE tran_33
DBCC upgrade_object: There's a difference between the objectname tran_33 and the name tran_33 used in syscomments.
DBCC upgrade_object: Maybe the object was renamed using sp_rename.
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.itxxn_33', Line 40:
#old_33 not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
Msg 207, Level 16, State 4:
Server 'DEV_RP', Line 3:
Invalid column name 'eryCmt'.
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.yftran_33', Line 40:
bat not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.yftran_33', Line 40:
#wbat not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
]
예 - 유효하며 출력에 캡처되어야 합니다.
{
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.itxxn_33', Line 40:
#old_33 not found. Specify owner.objectname or use sp_help to check whether the object exists
}
예 - 유효하지 않으며 출력에 캡처해서는 안 됩니다.
{
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.yftran_33', Line 40:
bat not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
}
답변1
빈 줄이 가짜 편집 아티팩트라고 가정합니다.
참고: input2.txt
이는 불필요한 줄바꿈이 제거된 예시 입력의 편집된 사본입니다.
$ sed -E -e 's/^(Msg |\])/\n\1/; s/\[/[\n/' input2.txt |
perl -00 -l -n -e 'print if /^Msg 208.*^#.*not found/ms'
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.itxxn_33', Line 40:
#old_33 not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.yftran_33', Line 40:
#wbat not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
sed
이는 입력을 Msg
각 행이 또는 의 각 인스턴스로 시작하는 단락 으로 변환하는 데 사용됩니다 . 그런 다음 의 출력은 단락 모드( )에서 입력을 읽기 위해 파이프되고 단락을 인쇄합니다.[
]
sed
perl
-n
-00
만약에 그리고 만약에이는 정규식과 일치합니다 ^Msg 208.*^#.*not found
(Perl의 m
수정자를 사용하여 각 단락을 여러 줄 문자열로 처리하고 s
수정자를 사용하여 .
일치하는 개행을 허용함).
"단락"은 하나 이상의 줄 바꿈으로 구분된 하나 이상의 텍스트 줄입니다.
Perl 명령줄 옵션에 대한 자세한 내용 man perlrun
과 Perl 정규식에 대한 자세한 내용은 을 참조하십시오 man perlre
. Perl 스크립트에서 정규식을 사용하는 방법에 대한 튜토리얼을 보려면 를 참조하세요 man perlretut
.
에서 man perlre
:
m
일치하는 문자열을 여러 줄로 처리합니다. 즉, 문자열의 첫 번째 줄의 시작과 마지막 줄의 끝을 일치시키는 것에서 문자열의 모든 줄의 시작과 끝을 일치시키는^
것으로 변경합니다.$
s
문자열을 한 줄로 처리합니다. 즉,.
일반적으로 일치하지 않는 모든 문자, 개행 문자까지 일치하도록 변경합니다.함께 사용하면 문자열의 개행 문자 뒤와 앞의 문자를 각각 허용하고 일치시키면서 모든 문자 일치를
/ms
허용합니다 ..
^
$
덧붙여서, 이 작업은 완전히 Perl에서 수행될 수도 있지만 sed
입력을 Perl의 단락 모드에서 쉽게 처리할 수 있는 것으로 변환하는 것이 더 간단하고 쉽고 빠릅니다.
또한 btw, 중괄호를 출력에 포함하려면 행을 다음 print if ...
으로 변경하십시오.print "{\n$_\n}\n" if ...
원래 요청한 것과 반대로 인쇄합니다(예: 다음 으로 Msg
시작하는 줄이 포함된 단락을 인쇄합니다).아니요포함 ^Msg 208.*^#.*not found
) if ...
명령문을 로 변경합니다 if (/^Msg /ms && ! /^Msg 208.*^#.*not found/ms)
. 즉, (가독성을 위해 추가 줄 바꿈 및 들여쓰기가 포함됨):
sed -E -e 's/^(Msg |\])/\n\1/; s/\[/[\n/' input2.txt |
perl -00 -l -n -e 'print if (/^Msg /ms &&
! /^Msg 208.*^#.*not found/ms)'
답변2
모든 Unix 시스템의 모든 쉘에서 awk를 사용하십시오.
$ cat tst.awk
/^#[^ ]+ not found/ && (p2 ~ /^Msg 208,/) {
print "{" ORS p2 ORS p1 ORS $0 ORS "}"
}
{ p2=p1; p1=$0 }
$ awk -f tst.awk file
{
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.itxxn_33', Line 40:
#old_33 not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
}
{
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.yftran_33', Line 40:
#wbat not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
}
위의 내용은 질문의 예상 출력이 잘못되었고 포함된 블록이 #wbat
출력에 포함되어야 한다고 가정하고 더 나아가 각 출력 블록이 여기에 래핑되어야 한다고 가정합니다. {...}
이것이 잘못된 가정인 경우 변경은 사소합니다.
답변3
다음과 같이 한 번에 이러한 행을 추출할 수 있습니다 sed
.
sed -n '1N;N;/Msg 208.*\n.*\n#[[:alnum:]_]* not found/p;D'
-n
정상적인 출력을 억제하는 옵션N;D
항상 두 줄을 함께 처리하는 시나리오는1N
파일 시작 부분에 세 번째 줄을 추가합니다.- 패턴은 인쇄하려는 트리플을
Msg 208.*\n.*\n#[[:alnum:]_]* not found
설명합니다 .p
각 일치 항목을 중괄호로 묶으려면 다음을 수행하십시오.
sed -n '1N;N;h;s/Msg 208.*\(\n\).*\n#[[:alnum:]_]* not found.*/{\1&\1}/p;g;D'
ubstitute 명령은 s
중괄호와 추가 개행 문자를 추가합니다( 대체 시 정의되지 않았기 때문에 캡처 \(\n\)
하여 재사용함 ). 물론 원본 내용을 기존 공간에 저장한 후 사용해야 합니다 .\1
\n
h
g