사실 제 이전 포스팅과 관련이 있는 내용인데특정 파일 확장자를 검색하여 디렉토리 정렬이것은 아직 답이 없습니다. 이 문제를 해결하는 데는 여러 가지 옵션이 있지만 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
두 번째는 grep
STDIN을 통해 구문 분석된 입력을 제공하기 때문에 작동합니다. 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
텍스트가 포함된 파일을 반환하려는 것 같습니다 . 그러니 이것을 시도해 보세요:*.out
index123
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
할 수 있으므로 데스크톱으로 가져올 필요조차 없습니다 .find
grep
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 문자를 사용할 때 추가 예방 조치를 취하지 않는 한 일반적으로 안전하지 않기 때문입니다.
관련된: