폴더에 속한 디렉터리의 파일 목록을 반복하면서 해당 폴더의 하위 디렉터리를 나열하고 해당 하위 디렉터리에 있는 동안 grep 표현식과 일치하지 않는 파일만 나열하려고 합니다. 그러나 grep
표현식이 포함된 결과 가 반환되지 않습니다 .
예를 들어:
for file in "ML"*; do if [ -d "$file" ]; then ls "$file" | grep -q -F "venv" ; fi; done
아무것도 인쇄되지 않습니다.
하위 디렉터리는 다음과 같습니다.
MachineLearning ROC.png bin requirements.txt venv
ACTION_batched.py PUT3.py test1.py
ACTION_custom.py RML test2.py
Case scenarios.docx Tutorials venv
ENV_DIR act_2.py week1
Introduction to essay.docx bin week2
MLschema.docx cookies.js week3
POST.py exercises week4
POST_T.py plots week5
PUT.py requirements.txt week6
PUT2.py somefig.jpeg week7
답변1
일치하는 디렉토리를 찾으려면 간단히 사용할 수 있습니다
printf '%s\n' ML*/venv/
cut -d / -f1
디렉토리 이름만 원하면 파이프로 연결하면 됩니다.
디렉토리 이름에 개행 문자가 있으면 완전히 올바르게 작동하지 않을 수도 있습니다.https://mywiki.wooledge.org/BashFAQ/020
시도의 문제점은 grep -q
아무것도 인쇄되지 않는다는 것입니다. 최소한의 수정은 삭제하는 것입니다 -q
. 그러나 물론 위에서 언급한 것처럼 단일 와일드카드를 사용하여 해결할 수 있습니다.
일치하지 않는 디렉터리를 원하는 경우(이에 대한 가장 작은 수정은 grep -v
부정적인 검색입니다) 다음과 같이 시도해 보십시오.
for file in ML*/*/; do
case $file in
*/venv/) continue;;
esac
: continue with "$file"
done
마지막 후행 슬래시는 와일드카드를 일치하는 디렉터리로만 제한합니다. 일반 파일도 일치시키려면 case
일치 표현식에서도 이를 제거 해야 합니다 venv
.
이 키워드는 루프의 가장 안쪽 또는 continue
현재 반복을 버리고 다음 반복(또는 이것이 마지막 반복인 경우 루프의 끝)으로 점프합니다.for
while
이전에 이 구문을 접해본 적이 없다면 case
두렵거나 신비스러워 보일 수 있지만 금방 익숙해질 것입니다. 이는 매우 일반적이며 대안을 쉽게 지정할 수 있습니다.
*/venv/ | */ENV_DIR/) continue;;
또한 원래 Unix v7 Bourne 셸로 다시 포팅할 수도 있습니다.
Bash와 Ksh에는 유사한 내용을 말할 수 있는 확장된 글로빙 도구가 있지만 ML*/!(venv)
이식성이 없습니다.