특정 디렉터리 내에서 파일을 포함하지 않는 디렉터리만 찾기

특정 디렉터리 내에서 파일을 포함하지 않는 디렉터리만 찾기

나는 큰 프로젝트를 가지고 있고 파일을 포함하지 않는 디렉토리를 찾으려고 노력하고 있습니다 *_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명령은 docgold디렉터리를 제외하지만 파일이 있는 디렉터리는 제외하지 않으며 *_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

작업이 반복적입니다이 문제. 동일한 전략이 작동합니다.

  1. 모든 *_out.csv 파일을 찾아 기본 이름을 제거하고 목록을 uniq하십시오.

  2. 원하는 모든 디렉토리를 찾으세요희망*_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

관련 정보