다음과 같이 로그 파일 세트를 중앙 디렉터리에 출력하는 애플리케이션이 있습니다.
/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
했습니다 .sort
uniq
$ 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
반복 됩니다-P
Perl
옵션은 정규식 스타일을 활성화합니다 .-o
옵션은 일치하는 부품을 선택합니다.-h
옵션은 파일 이름 인쇄를 억제합니다.