여러 파일에서 마지막으로 나타나는 문자열 찾기 이것은 내가 쓴 명령입니다. find . -mtime

문자열의 마지막 항목을 찾으려면 여러 로그 파일 (지난 24 시간 동안 생성 된 모든 파일을 모두 동일한 디렉토리에 유지)을 검색해야합니다. 이것은 내가 쓴 명령입니다.

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

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



답변

GNU 기능을 가정 :

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

답변

모든 것이 단일 디렉토리에있는 경우 다음을 수행 할 수 있습니다.

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

답변

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

… eparate files 옵션과 POSIX sed를 지원하는 GNU 가 있는 경우 작동합니다 .-sfind

디렉토리를 읽으려고 시도해도 유용하지 않으므로 일반 파일로 범위를 좁 히면 파이프 또는 직렬 장치 파일에서 읽기가 중단되는 것을 피할 수 있기 때문에 ! -type d또는 -type f한정자를 추가해야 합니다.

논리는 매우 간단 sed합니다. h이전 공간을 일치하는 입력 행의 복사본으로 덮어 쓴 searchstring다음 d모든 입력 행의 출력에서 ​​각 입력 파일의 마지막 행 을 생략합니다. 마지막 행에 도달하면 x보류 및 패턴 공간이 변경되므로 searchstring파일을 읽는 동안 발견 된 경우 마지막으로 발생한 항목이 출력되도록 자동 인쇄되고, 그렇지 않으면 빈 행을 씁니다. ( 원치 않는 경우 스크립트 /./!d의 꼬리 부분에 추가하십시오 sed) .

이것은 sed약 65k 입력 파일마다 또는 ARG_MAX한도에 관계없이 단일 호출 을 수행합니다 . 이것은 매우 성능이 뛰어난 솔루션이어야하며 매우 간단하게 구현됩니다.

최신 GNU가 주어지면 파일 이름을 원한다면 명령을 사용하여 파일 sed을 별도의 줄에 작성 F하거나 find배치 -print후 별도의 목록으로 인쇄 할 수 있습니다 +.


답변

어때요 :

find . -mtime -1 -name "fileprefix*" -exec sh -c \
'echo "$(grep 'search string' $1 | tail -n 1),$1"' _ {} \;

위의 내용은 각 파일에서 마지막으로 나타나는 검색 문자열과 쉼표 뒤에 각각의 파일 이름이 나오는 멋진 결과를 제공합니다 (에코 아래에서 “, $ 1″부분을 수정하여 포맷을 변경하거나 필요없는 경우 제거). 접두사가 “file”인 파일에서 ’10’검색 문자열을 검색하는 샘플 출력은 다음과 같습니다.

[dmitry@localhost sourceDir]$ find . -mtime -1 -name "file*" -exec  sh -c 'echo "$(grep '10' $1 | tail -n 1),$1"' _ {} \;
Another data 02 10,./file02.log
Some data 01 10,./file01.log
Yet another data 03 10,./file03.log 

답변

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항상 파일 이름과 모든 일치의 LINENUMBER 모두를 인쇄하려면 옵션을, 다음은 파일 이름과 LINENUMBER하고, AWK에 파이프를에 의해 정렬하는 저장 배열에있는 각 파일 이름의 마지막 경기, 결국 인쇄 그것.

상당히 무차별 한 방법이지만 작동합니다.