grep -c 출력에 mtime을 추가하고 mtime별로 출력을 정렬합니다.

grep -c 출력에 mtime을 추가하고 mtime별로 출력을 정렬합니다.

다음 이름을 가진 로그로 가득 찬 디렉터리가 있습니다.

info.log00001
info.log00002
info.log00003
...
info.log09999
info.log


내 현재 출력(grep -c 사용)

가끔 특정 오류가 얼마나 자주 발생하는지 분석해야 하므로 해당 디렉토리로 이동하여 grep -crw . -e "FooException BarError" | sort -n | less다음을 사용하여 다음과 같은 것을 얻으십시오.

./info.log00001: 1
./info.log00002: 0
./info.log00003: 42
...
./info.log09999: 25
./info.log: 0

ls -lt그런 다음 수정 날짜를 확인하고 가장 많은 오류가 발생한 시기를 분석할 수 있습니다.


내가 원하는 출력(개수 및 날짜 포함)

어쨌든, 같은 줄에 개수와 날짜를 출력할 수 있는 방법을 찾고 싶습니다. 이렇게 하면 내 분석이 더 쉬워질 것입니다. 나는 다음과 같은 것을 원합니다 :

2015-09-31 10:00 ./info.log00001: 1
2015-09-31 10:15 ./info.log00002: 0
2015-09-31 10:30 ./info.log00003: 42
...
2016-04-01 13:20 ./info.log09999: 25
2015-09-31 13:27 ./info.log: 0


추가 정보

이상적으로는 단 하나의 명령으로 이 작업을 수행하고 싶지만 먼저 grep명령의 출력을 파일에 넣은 다음 해당 파일을 처리하는 것도 가능합니다.

또한 날짜 형식이나 날짜가 줄의 끝인지 줄의 시작인지에 대해서는 별로 신경 쓰지 않습니다. 내가 원하는 것은 파일을 가장 오래된 것부터 시작하여 날짜별로 정렬하는 것입니다(이름에서 가장 작은 숫자가 있는 파일이기도 함).

달성할 수 있는 방법을 찾았습니다.비슷한 것awkgrep, 그러나 제 경우에는 의 출력에서 ​​파일 이름을 구문 분석하기 때문에 작동하지 않습니다 . 제 경우에는 grep의 출력에 파일 경로보다 더 많은 텍스트가 포함되어 있습니다.

이에 대한 피드백을 주시면 정말 감사하겠습니다.

답변1

gnu find파일 이름에 개행 문자가 포함되어 있지 않다고 가정하면 ' find를 사용할 수 있습니다.-printf원하는 형식으로 mtime+ 파일 이름을 출력하고 실행하여 grep개수를 얻습니다.

find . -type f -printf '%TY-%Tm-%Td %TH:%TM %p: ' -exec grep -cw "whatever" {} \; | sort -k1,1 -k2,2

또는 zsh수정 시간을 기준으로 전역적으로 정렬할 수 있습니다(다음을 통해).글로벌 예선.- 일반 파일 선택 , Om내림차순 정렬시간) 그런 다음 각 파일에 대해 mtime인쇄를 사용합니다.stat모듈, 파일 이름을 입력하고 다음을 통해 다시 개수를 가져옵니다 grep.

zmodload zsh/stat
for f in ./**/*(.Om)
do
printf '%s %s\t%s %s: ' $(zstat -F '%Y-%b-%d %H:%M' +mtime -- $f) $f
grep -cw "whatever"  $f
done

답변2

배쉬 구성

shopt -s globstar
join -o 1.2,0,2.2 -t$'\034' <(stat -c $'%n\034%y' ** | sort) \
                            <(grep -crw "..." | sort | sed -r $'s/:([^:]*)/\034\\1/') \
                             | tr '\034' '\t'

거기에는 뭔가 흥미로운 것이 있는데 \034, 그것은 문자의 8진수 값입니다 FS. 이것은그것은 상상할 수 있다기존 파일 이름에 이 문자가 포함된 경우 필요한 경우 구분 기호를 변경할 수 있습니다.

stat명령은 각 파일의 파일 이름과 수정 시간을 반복적으로 출력합니다.

grep 명령에 익숙합니다. 마지막 콜론을 FS 문자로 번역했습니다.

FS 문자를 얻으려면 bash의 ANSI-C 인용 구문을 stat 및 sed와 함께 사용해야 합니다.

join명령은 stat 출력을 grep 출력과 연결하고 "date FS filename FS count"를 출력합니다.

그런 다음 FS를 일반 탭으로 변환했습니다.

답변3

Perl 기반 솔루션:

perl -lne 'if ($.==1) {
 print localtime($t)." $f: $c\n" if defined $t; 
 $c=0; $f=$ARGV; $t=(stat($f))[7];} $c++ if /$expr/o; 
} BEGIN { $expr=shift @ARGV; push @ARGV,"/etc/hosts"; 
' "search-expression" info.log

참고: 테스트되지 않았습니다.

여기에 몇 가지 표준 Perl 팁이 있습니다. 코드를 -n둘러싸세요 . 1 while (<>) {이면 $.새 파일입니다. 파일을 처리하는 경우 타임스탬프, 파일 이름, 개수 등 요약 정보를 인쇄합니다. 이제 첫 번째 줄에 대해서만 현재 파일 이름, 파일의 mtime 타임스탬프를 가져오고 카운터를 재설정합니다. 각 줄에 대해 필요한 정규식과 일치하면 카운터를 늘립니다. while 루프를 종료하고 실행되는 일부 시작 코드를 시작합니다.앞으로이전 블록. 첫 번째 인수를 정규식으로 사용하여 각 줄에서 일치시킵니다. 이제 매개변수 목록에서 첫 번째 매개변수를 삭제합니다. 그 다음에,추가의최종 표현식을 트리거하는 더미 파일이 인수 목록에 추가됩니다 print. 이것은 무해한 해킹입니다.

관련 정보