내 상위 디렉터리에는 150개의 디렉터리가 있습니다. 그들 중 일부는 .txt
문서를 갖고 있고 다른 일부는 그렇지 않습니다. 파일이 없는 폴더를 인쇄하고 싶습니다 .txt
. 이 목표를 어떻게 달성할 수 있나요?
답변1
for dir in */; do
set -- "$dir"/*.txt
[ ! -e "$1" ] && printf '%s\n' "$dir"
done
이는 현재 디렉토리의 모든 디렉토리를 반복합니다. 각 디렉토리에 대해 .txt
위치 set
인수( , 등)를 패턴과 일치하는 파일의 경로 이름 $1
으로 설정하거나, 아무것도 일치하지 않는 경우 패턴 자체로 설정합니다. 이 파일 이름 확장의 첫 번째 결과가 기존 파일의 경로 이름이 아닌 경우 디렉터리 이름이 인쇄됩니다.$2
$1
현재 디렉토리를 포함한 모든 디렉토리에 대해 이 작업을 반복적으로 수행하려면 다음을 수행하십시오.
find . -type d -exec sh -c '
for dir do
set -- "$dir"/*.txt
[ ! -e "$1" ] && printf "%s\n" "$dir"
done' sh {} +
find
이는 디렉토리 경로 이름의 생성기 로 사용됩니다 . 일괄적으로 발견된 디렉토리 경로 이름에 대해 이전과 동일한 루프를 수행하여 포함되지 않은 이름을 인쇄합니다 .txt
.
위의 두 코드 모두 다음 항목의 존재를 감지합니다.어느이름은 로 끝납니다 .txt
. 관심이 있으신 경우일반 파일(또는 일반 파일에 대한 심볼릭 링크) 다음을 루프 본문으로 사용합니다.
while [ "$#" -gt 0 ] && [ ! -f "$1" ]; do
shift
done
[ ! -e "$1" ] && ...as above...
포함하다숨겨진파일 이름(예: with bash -O dotglob -c
대신 사용 ) 이로 인해 쉘 루프의 파일 이름 글로빙이 점으로 시작하는 이름도 고려하게 됩니다. 첫 번째 변형에서는 루프를 실행하는 경우 셸 옵션을 설정해야 합니다 .sh -c
find
dotglob
shopt -s dotglob
bash
답변2
나는 다음과 같은 방법으로 이를 달성할 수 있었습니다.
#!/bin/bash
search_dir=~/tmp
dirs=( $( find "$search_dir" -type f -name "*.txt" -exec dirname {} \; | sort -u ) )
exclude=()
for dir in "${dirs[@]}"; do
exclude+=( -not -path "$dir" )
done
find "$search_dir" "${exclude[@]}" -type d
변수를 search_dir
사용하려는 상위 디렉터리로 변경합니다.
그런 다음 dirs
각 디렉토리에 배열을 설정합니다.하다.txt 파일이 포함되어 있습니다.
exclude
그런 다음 각 디렉토리는 에 입력할 수 있는 형식으로 배열에 추가됩니다 find
. 그런 다음 제외 배열에 없는 모든 디렉터리에 대해 상위 디렉터리를 다시 검색합니다.