여러 파일에서 마지막으로 나타나는 문자열 찾기

여러 파일에서 마지막으로 나타나는 문자열 찾기

마지막으로 나타나는 문자열을 찾으려면 여러 로그 파일(모두 지난 24시간 내에 생성되고 모두 동일한 디렉터리에 저장됨)을 검색해야 합니다. 제가 쓴 명령은 다음과 같습니다.

find . -mtime 1 | grep fileprefix | xargs grep 'search string' | tail -1

그러나 이것은 파일의 마지막 줄만 반환합니다. 모든 라인을 얻기 위해 조정하는 방법에 대한 제안 사항이 있습니까?

답변1

모든 것이 하나의 디렉토리에 있으면 다음을 수행할 수 있습니다.

for file in *fileprefix*; do
    grep 'search string' "$file" | tail -1
done

tac대용량 파일인 경우 파일을 역순으로(마지막 줄부터) 인쇄한 다음 grep -m1첫 번째 항목과 일치시켜 작업 속도를 높이는 것이 좋습니다 . 이렇게 하면 전체 파일을 읽을 필요가 없습니다.

for file in *fileprefix*; do
    tac file | grep -m1 'search string'
done

두 가지 모두 일치하는 디렉터리가 없다고 가정합니다 fileprefix. 오류가 있는 경우 무시할 수 있는 오류가 발생합니다. 이것이 문제인 경우 파일을 확인하십시오.

 for file in *fileprefix*; do
    [ -f "$file" ] && tac file | grep -m1 'search string'
 done

파일 이름도 인쇄해야 하는 경우 -Hgrep호출에 해당 이름을 추가하세요. 또는 grep지원하지 않는 경우 검색도 수행하도록 지시합니다 /dev/null. 이는 출력을 변경하지 않지만 grep여러 파일이 제공되므로 항상 각 히트의 파일 이름을 인쇄합니다.

for file in *fileprefix*; do
    grep 'search string' "$file" /dev/null | tail -1
done

답변2

GNU 기능을 가정하면:

find . -mtime -1 -exec bash -c \
'for f; do tac "$f" | grep -m1 fileprefix; done' _ {} +

답변3

find . ! -name . -prune -mtime 1 -name 'fileprefix*' \
     -exec sed -se'/searchstring/h;$!d;x' {} +

sed... 독립형 파일 옵션과 POSIX 를 지원하는 GNU가 있는 경우 -s작동합니다 find.

그러나 디렉토리를 읽으려고 시도하는 것은 그리 유용하지 않으며 일반 파일로 범위를 좁히면 파이프나 직렬 장치 파일을 읽는 것을 방지할 수 있으므로 ! -type d또는 한정자를 추가해야 합니다 .-type f

논리는 매우 간단합니다. 이전 공간을 일치하는 입력 줄의 복사본으로 덮어쓴 다음 sed출력에서 ​​각 입력 파일의 마지막 입력 줄을 제외한 모든 줄을 제거합니다. 마지막 줄에 도달하면 유지 및 패턴 공간이 변경되므로 파일을 읽는 동안 마지막 이벤트가 발견되면 자동으로 출력에 인쇄되고, 그렇지 않으면 빈 줄이 작성됩니다.hsearchstringdxsearchstring/./!d( 필요하지 않은 경우 스크립트 끝에 추가 )sed.

sed이는 약 65,000개의 입력 파일 또는 제한 ARG_MAX에 관계없이 한 번의 호출을 수행합니다. 이는 성능이 매우 뛰어나고 구현이 매우 간단한 솔루션이어야 합니다.

최신 GNU에서 파일 이름 도 필요한 경우 sed이 명령을 사용하여 별도의 줄 에 F쓰거나 .find-print+

답변4

find . -mtime 1 -name 'fileprefix*' -exec grep -Hn 'search string' {} + |
    sort -t: -k1,2 -n | 
    awk -F: '{key=$1 ; $1="" ; $2="" ; gsub(/^  /,"",$0); a[key]=$0} 
             END {for (key in a) { print key ":" a[key] }}'

이는 GNU grep-H옵션을 사용 -n하여 일치하는 모든 파일 이름과 줄 번호를 항상 인쇄한 다음 파일 이름과 줄 번호별로 정렬하고 이를 awk로 파이프하여 각 파일 이름의 마지막 일치 항목을 배열에 저장하고 마지막으로 인쇄합니다.

이것은 다소 폭력적인 방법이지만 효과가 있습니다.

관련 정보