while 루프에서 특정 검색으로 파일 찾기 [닫기]

while 루프에서 특정 검색으로 파일 찾기 [닫기]

사실 제 이전 포스팅과 관련이 있는 내용인데특정 파일 확장자를 검색하여 디렉토리 정렬이것은 아직 답이 없습니다. 이 문제를 해결하는 데는 여러 가지 옵션이 있지만 while특히 루프에 관심이 있습니다. 현재 작업 디렉터리에서 무언가를 루프로 스캔하여 특정 파일이 있는지 검색 while한 다음 해당 폴더 이름만 인쇄하고 싶습니다 . 현재 작업 디렉터리에는 많은 폴더와 하위 폴더가 있습니다. 이것은 내 스크립트입니다.

while IFS= read -r d; do  
   if [[ "$d"=="*.out" && grep "index123"]]; then exit 1;  fi  
done <<  (find . -prune -type d) 

if강제가 루프 내에서 또는 다른 방법으로 수행하는 올바른 방법인지 모르겠습니다 . 안내해주세요.

답변1

grep이 실패하는 이유

터미널에서 다음을 수행하십시오.

실패 - 입력 대기 중
$ grep "index123"
작업 중 - STDIN에서 입력 수신
$ echo -e "line1\nline2\nindex123blah\n" | grep "index123"
index123blah

두 번째는 grepSTDIN을 통해 구문 분석된 입력을 제공하기 때문에 작동합니다. grep입력은 STDIN 또는 파일에서 가져옵니다. 귀하의 시나리오에서:

if [[ "$d"=="*.out" && grep "index123"]]; then exit 1;  fi  

또한 구문 분석하지 않으므로 실패합니다.

너의 문제

귀하의 코드로 판단하면 귀하가 이와 같은 것을 원한다고 생각합니다. 먼저, 다음은 몇 가지 샘플 데이터입니다.

$ mkdir -p 1/2/{3..5}
$ echo "index123" > 1/2/3/blah.out
$ echo "index123" > 1/2/3/blip.out
$ echo "index" > 1/2/blip.out
$ echo "index" > 1/2/blah.out

그리고 스크립트의 수정된 형식은 다음과 같습니다.

$ cat loopy.bash
#!/bin/bash

while IFS= read -r d; do  
  grep -l "index123" "$d" && exit 1
done < <(find . -type f -name "*.out") 

달리기:

$ ./loopy.bash
./1/2/3/blah.out

index123문자열이 포함된 첫 번째 파일을 내보낸 다음 종료합니다.

while 루프에 대한 좋은 솔루션이 있습니까?

나는 이것을하지 않을 것입니다. while이런 식으로 루프를 사용할 필요는 없습니다. find .... | xargs ...아키텍처나 find ... -exec솔루션 유형을 사용하는 것이 좋습니다 .

바라보다@DopeGhoti의 답변find또는 를 사용하는 더 나은 방법을 얻으려면 -exec.xargs

포함 디렉토리 인쇄

일치하는 파일이 있는 포함 디렉터리 트리를 인쇄하려면 dirname다음과 같이 할 수 있습니다.

$ cat loopy2.bash
#!/bin/bash

 while IFS= read -r d; do
   grep -q "index123" "$d" && dirname "$d"  && exit 1
 done < <(find . -type f -name "*.out")

그리고 실행하세요:

 $ ./loopy2.bash
./1/2/3

답변2

귀하의 질문은 다음과 같습니다.

if [[ "$d"=="*.out" && grep "index123"]];

가설을 세워보자 d=foo.out. 이제 우리는 다음을 효과적으로 갖췄습니다:

if [[ grep "index123"]];

grep그래서 당신은 표준 입력에서 표현식을 검색하라고 지시하려고 합니다 /index123/. 그러나 입력이 도달하지 않으므로 입력을 기다리는 동안 중단되는 것 같습니다.하지만if [[ grep "index123" ]], 표면적으로 구문이 유효하지 않기 때문에 그렇게까지 진행되지는 않습니다 . 대신에, 당신은 원할 것입니다 if grep "index123". 그러나 다시 말하지만, 표준 입력이 오기를 기다리고 있습니다.

find텍스트가 포함된 파일을 반환하려는 것 같습니다 . 그러니 이것을 시도해 보세요:*.outindex123

find . -prune -type d -name \*.out -print0 | xargs -0 grep -l 'index123'

그러나 이 find진술은 상당히 복잡하다. find우리가 원하는 실제 파일을 검색할 수 있는데 왜 모든 작업을 수행한 다음 디렉토리를 정리합니까?

find . -type f -name \*.out -print0 | xargs -0 grep -l 'index123'

이제 찾고 있는 텍스트가 포함된 모든 파일이 표시됩니다.

하지만 별도로 호출 xargs할 수 있으므로 데스크톱으로 가져올 필요조차 없습니다 .findgrep

find . -type f -name \*.out -exec grep -l 'index123' "{}" \;

답변3

*.out현재 디렉터리에서 이 문자열을 포함하는 모든 파일을 찾습니다 .index123

grep -lF 'index123' ./*.out

현재 디렉터리 아래 어디에 있든 grep모든 파일을 반복적으로 검색 하려면 다음을 수행하세요 .*.out

find . -type f -name '*.out' -exec grep -lF 'index123' {} +

문자열이 발견된 디렉터리를 인쇄합니다.

find . -type f -name '*.out' -exec grep -qF 'index123' {} ';' -exec dirname {} ';'

처음으로 디렉터리 이름을 찾은 후 종료합니다(GNU 사용 find).

find . -type f -name '*.out' -exec grep -qF 'index123' {} ';' -exec dirname {} ';' -quit

다음 계획에 따라 다름사용디렉터리 이름 -quit을 다른 이름으로 바꾸어 -exec필요한 방식으로 디렉터리를 조작하거나 다양한 -exec유틸리티를 from 이라는 쉘 스크립트에 결합할 수 있습니다 -exec. 너 뭐야아니요이는 디렉터리 이름을 다른 명령으로 파이프하는 것입니다. 이는 경로 이름을 구분하기 위해 Null 문자를 사용할 때 추가 예방 조치를 취하지 않는 한 일반적으로 안전하지 않기 때문입니다.

관련된:

관련 정보