여러 파일의 패턴과 일치하는 마지막 몇 줄을 가져옵니다.

여러 파일의 패턴과 일치하는 마지막 몇 줄을 가져옵니다.

다음과 같이 로그 파일 세트를 중앙 디렉터리에 출력하는 애플리케이션이 있습니다.

/tmp/experiment/log/    
├── node01.log
├── node02.log
├── node03.log
├── node04.log
├── node05.log
├── node06.log

각 파일 내에서는 각 로그 프로세스의 수명 동안 다양한 작업이 수행되므로 해당 줄은 다음과 같습니다.

prop1=5, ts=X, node01
prop2=3, ts=X, node01
prop1=7, ts=Y, node01
...

모든 파일을 처리하고 특정 속성의 마지막 읽기를 출력하는 몇 가지 명령을 작성하려고 합니다. 이상적으로 출력은 다음과 같습니다.

node01, prop1=7, ts=...
node02, prop1=9, ts=...
node03, prop1=3, ts=...

어떤 제안이 있으십니까? 나는 다음과 같이 , 의 조합을 사용 grep하기 시작 cut했습니다 .sortuniq

$ grep -sirh "prop1" /tmp/experiment/log/ | \
   cut --delimiter=, --fields=1,4 | uniq | sort | \
   tail -n 14`  --this example had 14 log files

그러나 일부 실험에서는 동일한 로그의 여러 레코드를 인쇄하고 일부 다른 로그를 제외하기 때문에 부분적으로만 작동합니다.

나는 계속했다 awk:

$ awk -F":" '/prop1/ { print $NF $2}' /tmp/experiment/log/node*.log | \
   awk 'END { print }'

그리고 여러 입력 파일을 전달할 때 로그 파일당 1개의 출력 줄이 아닌 마지막 로그 파일의 마지막 줄만 제공된다는 문제가 있습니다.

이를 달성하는 방법에 대한 제안이 있으십니까?

답변1

ENDFILE블록(GNU 특정)을 살펴보십시오 awk. 다음과 같이 뭔가를 실행할 수 있습니다

awk     'BEGINFILE { a = ""}
         /prop1/   { a=$NF $2 $1}    ## Change this if necessary
         ENDFILE   { if (a != "") print FILENAME, a}' ./node*.log

답변2

GNU's grep & sed다음과 같이 이 작업을 수행 할 수 있습니다 .

grep -zoPhr '(.*\n)+\Kprop1=[^\n]*' /tmp/experiment/log/ | sed 's/\(.*\),\s\(.*\)/\2, \1/'

설명하다:

  • -z옵션을 사용하면 grep파일이 \0.
  • -r옵션이 grep반복 됩니다
  • -PPerl옵션은 정규식 스타일을 활성화합니다 .
  • -o옵션은 일치하는 부품을 선택합니다.
  • -h옵션은 파일 이름 인쇄를 억제합니다.

관련 정보