처음에 나는 이것에 대한 해결책을 얻었습니다.우편 엽서.
그러나 이는 2가지 모드에서만 사용할 수 있습니다. 이제 2개 이상의 패턴, 어쩌면 3번째 패턴, 심지어 4번째 패턴이 필요하다는 것이 밝혀졌습니다.
@cas에서 얻은 패턴을 더 추가하여 다음 솔루션을 사용해 보았습니다.
awk -v OFS=, '
match($0,/\<[[:digit:]]{1,2}\/[[:digit:]]{1,2}\/[[:digit:]]{4} [[:digit:]]{1,2}:[[:digit:]]{1,2}\>/,a) {dt = a[0]; next};
match($0,/3rd pattern/,b);
match($0,/INC-[[:digit:]]+-[[:digit:]]+/,a) {print a[0], dt; print b[0]}' filename.log
나는 다음과 같은 결과를 얻었습니다.
INC-210305-00000426,3/6/2021 5:19
INC-20210304-00006690,3/5/2021 5:24
공간을 더 추가하면 됩니다. 세 번째 또는 네 번째 패턴을 찾는 방법에 대한 다른 제안이 있습니까? 그들은 실제로 다른 노선에 있습니다. 입력은 다음과 같습니다.
unwantedtext unwantedtext unwantedtext unwantedtext 8/1/2022 6:15 (1st Pattern)
unwantedtext unwantedtext unwantedtext unwantedtext
unwantedtext unwantedtext Report_A (3rd Pattern)
unwantedtext unwantedtext INC-220721-00007628 (2nd required pattern)
unwantedtext unwantedtext unwantedtext unwantedtext
unwantedtext unwantedtext Report_B (4th) Pattern)
원하는 출력은 다음과 같습니다.
INC-220721-00007628, 8/1/2022 6:15, Report_A
나중에 다음 출력이 필요할 수도 있습니다.
INC-220721-00007628, 8/1/2022 6:15, Report_A, Report_B
저는 Cygwin과 CentOS 7 환경을 사용하고 있습니다.
유용한 솔루션에 미리 감사드립니다.
답변1
perl
대신 사용하겠습니다 awk
(gawk도 사용합니다. 사용하는 코드는 gawk에 따라 다릅니다).
perl -l -0777 -ne '
$time = $& if m{\b\d{1,2}/\d{1,2}/\d{4} \d{1,2}:\d{1,2}\b};
$inc = $& if /\bINC-\d+-\d+\b/;
@reports = /\bReport_\S+/g;
print join ", ", $inc, $time, @reports
if defined($time) && defined($inc)' your-file
답변2
존재하다TxR:
$ txr extract.txr input
INC-220721-00007628, 8/1/2022 6:15, Report_A, Report_B
어디 extract.txr
:
@(skip)@{date /[^ ]+/} @{time /[^ ]+/} (1st Pattern)
@(skip)
@(skip)@{rep1 /[^ ]+/} (3rd Pattern)
@(skip)INC-@inccode (2nd required pattern)
@(skip)
@(skip)@{rep2 /[^ ]+/} (4th) Pattern)
@(output)
INC-@inccode, @date @time, @rep1, @rep2
@(end)
줄 끝의 패턴을 일치시키려면 여기에 약간의 정규 표현식이 필요합니다. 텍스트 캡처와 유사한 변수에는 @date
공백이 포함될 수 있지만 @{date /[^ ]+/}
공백이 아닌 일련의 문자를 캡처할 수 있습니다.
출력은 단 한 줄이므로 @(output)
...에 포함된 Lisp 함수 호출로 바꿀 수 있습니다.@(end)
@(do ...)
@(do (put-line `INC-@inccode, @date @time, @rep1, @rep2`))
답변3
POSIX awk를 사용하십시오.
$ cat tst.awk
match($0,/([0-9]{1,2}\/){2}[0-9]{4} [0-9]{1,2}:[0-9]{1,2}/) { dt = substr($0,RSTART,RLENGTH) }
match($0,/INC(-[0-9]+){2}/) { inc = substr($0,RSTART,RLENGTH) }
match($0,/Report_A/) { repa = substr($0,RSTART,RLENGTH) }
match($0,/Report_B/) { repb = substr($0,RSTART,RLENGTH) }
END { OFS=", "; print inc, dt, repa, repb }
$ awk -f tst.awk file
INC-220721-00007628, 8/1/2022 6:15, Report_A, Report_B
위의 내용은 대상 정규식의 중간 단어와 일치합니다. 질문의 예에서 이것이 가능성이라고 표시하지 않았지만 이것이 실제 데이터에 문제가 있는 경우 다음과 같이 변경하십시오.
$ cat tst.awk
function set(val) {
val = substr($0,RSTART,RLENGTH)
gsub(/^ | $/,"",val)
return val
}
match($0,/(^| )([0-9]{1,2}\/){2}[0-9]{4} [0-9]{1,2}:[0-9]{1,2}( |$)/) { dt = set() }
match($0,/(^| )INC(-[0-9]+){2}( |$)/) { inc = set() }
match($0,/(^| )Report_A( |$)/) { repa = set() }
match($0,/(^| )Report_B( |$)/) { repb = set() }
END { OFS=", "; print inc, dt, repa, repb }