수천 개의 로그 파일이 있는데 모두 매우 큽니다. 그 중 하나가 내가 찾고 있는 IP 주소를 갖고 있을 것입니다. 나는 그것이 파일 상단 근처에서 일어날 가능성이 가장 높다는 것을 알고 있습니다. 저 할 수 있어요:
head -n 500 *.log | fgrep myip
"예"가 표시되며 이는 로그 파일 중 하나에 있습니다. 그것이 어느 것인지 어떻게 결정합니까? 파일 크기로 인해 모든 파일(fgrep myip *.log)의 전체 내용을 grep하는 것은 불가능합니다.
답변1
awk만으로 탈출할 수 있습니다.
awk -v ip=127.0.0.1 'substr($0, ip) > 0 {print FILENAME ": " $0} FNR > 500 {nextfile}' *.log
현재 줄에서 IP가 발견되면 IP와 파일 이름을 인쇄합니다. 현재 파일( )의 현재 줄 번호가 500보다 크면 FNR
다음 파일로 점프합니다.
답변2
이와 같은 것이 도움이 될 것입니다.
find . -iname "*.log" -print0 | xargs -0 -i{} bash -c 'echo "»»»File Name: {}«««"; head -n 500 {} | fgrep -B 501 myip'
긴 파일 이름 목록을 생성한 다음 최대 500줄의 발견된 데이터, 긴 파일 이름 목록을 생성합니다. 원하는 파일 이름은 긴 데이터 문자열 바로 앞의 파일 이름입니다.
답변3
find -name \*.log -print0 |
xargs -0 sh -c 'for i; do head -n 500 $i | fgrep -q myip && echo $i; done
이는 .로 끝나는 모든 파일 이름을 찾아 .log
해당 목록을 xargs
.-print0
xargs -0
xargs
나중에 주어진 명령 xargs
과 해당 인수는 명령 호출에서 적절한 파일 이름으로 실행됩니다. 이 경우 주어진 명령은 sh
(shell)이며, 쉘에는 실행할 작은 쉘 스크립트가 제공됩니다.
쉘 스크립트는 기본적으로 다음과 같습니다.
for i; do
head -n 500 $i | fgrep -q myip && echo $i
done
이 for i
부분은 쉘에 제공된 모든 인수, 즉 모든 파일 이름을 반복합니다. 각 파일 이름에 대해 처음 500줄을 가져와서 지정된 문자열을 검색합니다. fgrep -q
이는 fgrep이 문자열을 발견하자마자 중지한다는 의미입니다. 문자열이 발견되면 종료 상태는 "성공"이고, 그렇지 않으면 "실패"입니다. 마지막으로 이는 && echo $i
이전 명령이 "성공" 상태인 경우 에코가 수행된다는 의미이며, 이는 문자열이 발견되면 파일 이름이 표시된다는 의미입니다.
답변4
저 할 수 있어요:
- 모든 파일을 반복합니다.
- 처음 500개 행을 가져옵니다.
- IP가 다음 줄에 있는지 확인하세요.
- 그렇다면 파일 이름을 인쇄하고 루프를 종료하십시오.
코드로:
for f in ./*
do
head -n 500 "$f" | grep -qF myip && { printf "Found in: $f"; break; }
done
myip
찾고 있는 IP로 교체하세요 . 원하는 IP를 매개변수로 검색하는 함수(또는 셸 스크립트)를 만들 수 있습니다.
findlogip ()
{
for f in ./*;
do
head -n 500 "$f" | grep -qF "$1" && {
printf "Found in: $f\n";
break
};
done
}
~처럼엠마 루오 댓글, 실수로 다른 IP와 일치하지 않도록 검색하는 IP에 주의해야 할 수 있습니다(예에서는 10.55.33.6이지만 110.55.33.68이 일치함). GNU grep을 사용하십시오(가정, 주어진운영 체제태그), 특정 IP 주소를 태그로 묶을 수 있습니다 \b
.
...
head -n 500 "$f" | grep -q "\b$1\b" && ...
...
-F
표현식이 더 이상 "고정" 표현식이 아니고 정규 표현식이기 때문에 (고정 문자열) grep 옵션을 제거합니다 .