로그 파일에서 날짜를 추출하고 고유한 날짜가 포함된 파일 만들기

로그 파일에서 날짜를 추출하고 고유한 날짜가 포함된 파일 만들기

파일에서 날짜 형식의 날짜를 추출하고 싶습니다 DD.MM.YYYY. 날짜는 항상 첫 번째 위치에 있습니다. 다음은 항목의 예입니다.

15.04.2016 13:13:30,228 INFO    [wComService] [mukumukuko@system/3] Call created with id:VoiceConnector$mukumukuko@system$D1:1:0:CB:SESSION$D1:1:0:DB:mukumukuko@system$D1:1:0:HB:_TARGET^M
15.04.2016 13:14:10,886 INFO    [wComService] Call 5303 from device +41999999999^M
15.04.2016 13:14:20,967 INFO    [AddressTranslatorService][mukumukuko@system/3] </convertLocalToGNF>^M
15.04.2016 13:14:20,992 INFO    [wComService] [mukumukuko@system/3] Call created with id: VoiceConnector$mukumukuko@system$D1:1:0:MB:SESSION$D1:1:0:NB:mukumukuko@system$D1:1:0:RB:_TARGET^M
15.04.2016 13:15:18,760 INFO    [OSMCService] SessionManager Thread - Heartbeat (1clients connected)^M

파일에는 1주간의 활동 로그가 포함되어 있으므로 파일에서 날짜(예: 16.04.2016, 17.04.2016, ) 도 찾을 수 있습니다 18.04.2016.

이 파일에는 Java 예외에 대한 다음 출력이 있을 수도 있습니다.

    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanEndElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)

나는 다음을 시도했습니다 :

cat fac.log | sed 's/^.*\([0-9]\{2\}.[0-9]\{2\}.[0-9]\{4\}\).*$/\1/' > datesF1

하지만 "datesF1"에 원하는 날짜가 표시되지만 이러한 Java 예외 메시지가 표시됩니다.

그래서 내가 원하는 것은 반복하지 않고 고유한 날짜만 표시하는 파일을 생성하는 것입니다. 예를 들어 "datesF1"은 다음과 같아야 합니다.

15.04.2016
16.04.2016
17.04.2016
18.04.2016

이것이 가능한지 또는 grep 명령을 사용하는 것이 더 나은지 알고 계십니까?

답변1

sed 명령이 작동하지 않는 이유는 각 줄에 날짜가 있다고 가정하기 때문입니다. 일부 줄이 여러 줄 오류 메시지에서 나온 경우에는 그렇지 않습니다. 교체 패턴과 일치하는 항목이 없으면 sed는 교체를 수행하지 않으며 표시되는 호출 스택 목록은 출력에 남아 있습니다.

시작 부분에 날짜가 포함된 행에서만 날짜를 가져오려면 다음과 같은 몇 가지 옵션이 있습니다.

그렙:

grep -Eo '^[0-9.]+' fac.log 

-o는 grep에게 전체 줄이 아닌 일치하는 부분만 인쇄하도록 지시하고 -E는 "확장" 정규식을 활성화합니다.

이상한:

awk '/^[0-9.]+/ {print $1}' fac.log

awk 명령의 첫 번째 부분은 정규식 일치이고 나머지는 일치하는 줄을 처리하는 방법입니다. 여기서는 줄의 첫 번째 단어를 인쇄합니다.

진주:

perl -lne 'print $1 if /^([0-9]+)/' fac.log

-l: 각 줄에 새 줄을 인쇄합니다 print. -n: 각 줄에 대해 실행 명령(예: awk)을 입력합니다. -e: 파일이 아닌 명령줄에서 제공되었음을 프로그램에 알립니다.

모든 경우에 일치하는 각 입력 행에 대해 하나의 출력 행(반복 날짜)을 얻습니다. 결과를 파이핑하는 | sort | uniq것은 아마도 중복을 제거하는 가장 간단한 방법일 것입니다.

제가 게을러서 ^[0-9.]+더 길고 정확한 패턴을 사용하지 않았다는 점에 유의하세요. 이는 내가 sed, awk 및 친구보다 Perl을 사용하는 것을 선호하는 이유와 관련이 있습니다. Perl 정규식은 무엇을 하든 항상 동일합니다. 또한 Perl에서는 어떤 수정자가 기본적으로 지원되는지, 어떤 수정자가 -E 등을 설정해야 하는지 기억할 필요가 없습니다. 그런 다음 버전 간에 차이가 있습니다. 분명히 내 데비안 시스템은 GNU awk 대신 mawk로 기본 설정되어 있고 {N} 수정자를 지원하지 않는 것 같아서 더 정확한 모드가 작동하지 않습니다. 이런.

GNU awk 매뉴얼: "간격 표현식은 전통적으로 awk에서 사용할 수 없습니다. 이는 awk와 egrep이 서로 일관성을 갖도록 하기 위해 POSIX 표준의 일부로 추가되었습니다."https://www.gnu.org/software/gawk/manual/html_node/Regexp-Operators.html#Regexp-Operators)

답변2

awk '/^[0-9]{2}[.][0-9]{2}[.][0-9]{4}/ {DATES[$1]++} 
     END{ for(d in DATES) {print d} }'

가위바위보와 종이의 차이점은 다음과 같습니다.항상 sed보다 낫습니다. :-)

편집: 이것이 실제로 작동하는 것입니다:

$ cut -b-60 t
15.04.2016 13:13:30,228 INFO    [wComService] [mukumukuko@sy
15.05.2016 13:14:10,886 INFO    [wComService] Call 5303 from
15.06.2016 13:14:20,967 INFO    [AddressTranslatorService][m
15.07.2016 13:14:20,992 INFO    [wComService] [mukumukuko@sy
15.04.2016 13:15:18,760 INFO    [OSMCService] SessionManager
this file contains the activity log of 1 week, so in the fil

The file can have also these outputs from Java exception:

    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanE
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl
    at org.apache.xerces.parsers.XML11Configuration.parse(Un
    at org.apache.xerces.parsers.XML11Configuration.parse(Un

$ awk '/^[0-9]{2}[.][0-9]{2}[.][0-9]{4}/ {DATES[$1]++} 
     END{ for(d in DATES) { print d } }' t
15.07.2016
15.06.2016
15.04.2016
15.05.2016

그것은 GNU awk입니다. awk 버전이 출력을 생성하지 않는 경우 정규식 구현이 다르고 어떤 줄과도 일치하지 않기 때문일 수 있습니다. 예를 들어 중괄호를 반복 지정자로 지원하지 않을 수 있습니다. 구체성을 잃는 대가로 정규식을 으로 단순화할 수 있으며 /^[0-9]/이는 확실히 작동합니다. 이렇게 하면 날짜가 캡처되고 로그 메시지가 제거되지만 날짜가 아닌 일부도 캡처할 수 있습니다.

친숙한 awk 매뉴얼을 사용하여 몇 가지 실험과 시간을 투자하면 유익한 결과를 얻을 수 있습니다. ;-)

관련 정보