첫 번째 일치 후 "찾기"를 종료하는 방법은 무엇입니까?

첫 번째 일치 후 "찾기"를 종료하는 방법은 무엇입니까?

나는 while 루프에서 find를 사용하고 있습니다. ip.txt의 IP 목록을 가져와 파일 디렉터리에서 IP를 검색하고 찾은 각 IP의 파일 이름을 results.res라는 파일에 기록합니다.

성공적으로 찾을 때마다 중지하고 다음 IP로 이동하고 싶습니다.

내 현재 스크립트는 다음과 같습니다

while read ip; do
    find . -type f -maxdepth 1 -not -name ips.txt -not -name results.res -print0  | xargs -0 grep "$ip" >> results.res
done < ips.txt

사이트에서 다른 답변을 조사한 결과 다음을 사용하여 발견했습니다.

-print -quit
-print | head -n 1

첫 번째 성공적인 검색 후 검색을 중지합니다. 그러나 while 루프를 사용하고 있으므로 이것이 작동하지 않습니다. 누구든지 가능한 솔루션을 제안할 수 있습니까?

답변1

while IFS= read -r ip; do
  find . -maxdepth 1 \
         -type f \
         ! -name ips.txt \
         ! -name results.res \
         -exec grep -lwFe "$ip" {} \; \
         -quit
done < ips.txt > results.res

파일의 각 줄을 변수 ips.txt로 읽고 $ip기준과 일치하는 파일을 찾아보고 find(특정 순서 없이) $ip고정 F문자열과 ord로 구분된 w첫 번째 파일을 보고합니다. 성공할 때 -quit호출되어 다음을 반환합니다 -exec.grep진짜일치하는 항목이 발견되면 종료 상태입니다.

답변2

현재 스크립트가 작성된 방식에 따라 를 실행 한 다음 찾은 모든 파일과 find에서 찾은 grep모든 파일을 실행합니다.ipips.txt

동일한 파일 목록을 얻기 위해 매번 실행할 필요가 없으므로 루프 find에서 꺼내어 while변수에 할당합니다. 또한 발견된 모든 파일에 대해 실행할 필요가 없으며 grep하나의 명령으로 모든 파일을 검색할 수 있습니다. 이제 파일 목록이 있으므로 grep각 파일에 대해 작업을 수행 ip하고 첫 번째 일치 항목만 반환할 수 있습니다. 이제 스크립트는 다음과 같습니다.

files=$(find . -maxdepth 1 -type f -not -name ips.txt -not -name results.res)
while read ip; do
    grep --with-filename --max-count=1 "$ip" $files | head -n 1 >> results.res
done < ips.txt

이것은 grep모든 in 명령의 모든 파일을 반복하며 find각 IP 주소와 해당 IP 주소가 발견된 첫 번째 파일을 포함하는 줄을 넣어야 합니다. ipips.txtresults.res

편집하다:

몇 가지 테스트를 거친 후에는 이전 코드가 공백이나 이상한 문자가 포함된 파일 이름을 전혀 처리하지 않기 때문에 더 나은 방법이 있는 것처럼 보입니다. find여기서는 필요 없을 것 같으니 없애겠습니다 .

및 를 grep제외한 현재 디렉터리의 모든 파일을 반복할 계획 이므로 다음을 찾지 않고도 사용할 수 있습니다 .results.resips.txtgrep

while read ip; do
    grep --with-filename --max-count=1 --exclude={results.res,ips.txt} "$ip" * | head -n 1 >> results.res
done < ips.txt

관련 정보