나는 큰 프로젝트를 가지고 있고 파일을 포함하지 않는 디렉토리를 찾으려고 노력하고 있습니다 *_out.csv
. 다른 유사한 답변을 살펴본 결과 거의 다 온 것 같습니다.
내가 겪고 있는 문제는 분석이 계속되는 디렉터리만 보고 싶지만 analysis/
분석되는 일부 특정 디렉터리는 보고 싶지 않다는 것입니다.
나는 작은 예제 문제를 설정했습니다.
$ tree
.
├── case1
│ ├── analysis
│ │ ├── test1
│ │ │ ├── gold
│ │ │ └── test1_out.csv
│ │ └── test2
│ └── doc
└── case2
├── analysis
│ ├── test3
│ │ └── gold
│ └── test4
│ └── test4_out.csv
└── doc
12 directories, 2 files
*/doc/*
또는이라는 제목의 디렉토리를 보고 싶지 않습니다 */gold/*
. 내 현재 명령은 다음과 같습니다
find . -type d -not -name "doc" -not -name "gold" '!' -exec test -e "{}/*_out.csv" ';' -print
결과 :
.
./case1
./case1/analysis
./case1/analysis/test1
./case1/analysis/test2
./case2
./case2/analysis
./case2/analysis/test3
./case2/analysis/test4
내 이상적인 출력은 다음과 같습니다
./case1/analysis/test2
./case2/analysis/test3
보시다시피 현재 find
명령은 doc
및 gold
디렉터리를 제외하지만 파일이 있는 디렉터리는 제외하지 않으며 *_out.csv
계속되지 않는 디렉터리도 제외하지 않습니다 analysis/
.
답변1
따라서 특정 하위 디렉터리를 제외하고 양식의 디렉터리를 보려고 합니다 */analysis
.
아래 내용을 모두 검색하지 말고 .
아래 내용만 검색하세요 */analysis
.
하위 디렉터리를 제외하려면 를 사용합니다 -prune
. 이는 find가 하위 디렉터리를 반복적으로 탐색하지 않도록 지시하는 작업입니다.
마지막으로 패턴과 일치하는 파일이 존재하는지 테스트하려면 셸을 호출해야 합니다. test
에서 직접 호출 하지만 find
패턴 test
일치가 없으므로 *
이름에 리터럴 문자가 포함된 파일이 있는지 테스트합니다. 호출하여 sh
디렉터리 이름을 인수로 전달합니다 -exec sh -c '…' {} \;
. sh 코드에서 와일드카드 문자를 확장하여 일치하는 파일 목록을 생성하고 기존 파일이 하나 이상 있는지 확인합니다.
find ./*/analysis -name "doc" -prune -o -name "gold" -prune -o \
-type d \! -exec sh -c 'set -- "$0"/*_out.csv; test -e "$1"' {} ';' -print
(이름이 로 끝나는 매달려 있는 심볼릭 링크는 없다고 가정합니다 _out.csv
.)
답변2
작업이 반복적입니다이 문제. 동일한 전략이 작동합니다.
모든 *_out.csv 파일을 찾아 기본 이름을 제거하고 목록을 uniq하십시오.
원하는 모든 디렉토리를 찾으세요희망*_out.csv 파일이 있을 것이며 목록 1의 항목은 2단계의 목록에서 제거됩니다.
스크립트는 이를 수행하기 위해 출력 설명자를 사용합니다.
echo "csv files exist in:"
find . -type f -name \*_out.csv | sed -e 's/\/[^\/]*$//' |
sort -u | tee csv-dirs.txt
echo
echo "dirs we hope would have csv's:"
find . -type d | egrep '/analysis/' | egrep -v '/(doc|gold)(/.*|)$' |
tee all-dirs.txt
echo
echo "all dirs less the ones that do have csv's:"
egrep -vxFf csv-dirs.txt all-dirs.txt
조금 요약하면 다음과 같습니다.
$ find . -type f -name \*_out.csv |
sed -e 's/\/[^\/]*$//' | sort -u > csv-dirs.txt
$ find . -type d | egrep '/analysis/' |
egrep -v '/(doc|gold)(/.*|)$' | egrep -vxFf csv-dirs.txt
./case1/analysis/test2
./case2/analysis/test3