하위 디렉토리를 포함하지 않는 디렉토리 찾기


10

스크립트 작성은 ksh입니다. 하위 디렉토리가 아닌 파일 만 포함하는 현재 디렉토리에서 모든 디렉토리 이름을 직접 찾아야합니다.

ls -alR첫 번째 필드의 첫 번째 문자 ( d디렉토리)의 출력을 사용 하고 재귀 적으로 구문 분석 할 수 있음을 알고 있습니다. awk파싱하고 찾는 가장 좋은 방법 이라고 생각 합니다.

예를 들어, ls -al현재 디렉토리 의 간단한 출력 :

   drwxr-xr-x  22 af      staff    748 18 Mar 22:21 .
   drwxr-xr-x   5 root    admin    170 17 Mar 18:03 ..
   -rw-------   1 af      staff      3 17 Mar 16:37 .CFUserTextEncoding
   drwxr-xr-x   5 af      staff    170 17 Mar 17:12 Public
   drwxr-xr-x   9 af      staff    306 18 Mar 17:40 Sites
   -rw-------   1 af      staff      3 17 Mar 16:37 textd
   

이이 출력이 디렉토리는 다음과 같습니다 PublicSites. 디렉토리 Public에는 하위 디렉토리 가 포함되어 있지 않지만 포함되어 있습니다 Sites. 에 3 개의 하위 디렉토리가 Sites있습니다. 따라서 디렉토리가 포함되지 않은 디렉토리 만 에코해야합니다. 제 경우에는 이건 오직 Sites입니다.

답변:


1

전혀 사용할 필요가 없습니다 awk. ksh다음과 같은 기능 을 제공 하는 내장 테스트를 사용하십시오 .

#!/bin/ksh

for NAME in *
do
    FOUND=no
    if [[ -d $NAME && $NAME != '.' && $NAME != '..' ]]
    then
        for SUBNAME in $NAME/*
        do
            if [[ -d $SUBNAME ]]
            then
                FOUND=yes
                break
            fi
        done
        if [[ $FOUND == no ]]
        then
            echo Found only files in $NAME
        fi
    fi
done

이 작은 스크립트는 현재 디렉토리의 모든 디렉토리를 살펴보고 하위 디렉토리가없는 파일 만 포함하는지 알려줍니다.


14

사용할 수 find있고 "일반 Unix 파일 시스템"(즉, -noleaf 옵션 설명의 find (1) 에 정의 된대로 ) 에서 작업중인 경우 다음 명령을 사용할 수 있습니다.

find . -type d -links 2

각 디렉토리에는 최소한 2 개의 이름 (하드 링크) .과 이름이 있습니다. 하위 디렉토리 (있는 경우) ..는 상위 디렉토리를 가리 키므로 N 하위 디렉토리가있는 디렉토리는 하드 링크 수가 N + 2와 같습니다. 따라서 하드 링크 수가 2 인 디렉토리를 검색하면 N = 0 서브 디렉토리를 가진 디렉토리를 검색합니다.

따라서을 사용할 수 있다면 find이것이 가장 빠른 방법이며 stat()각 구성원 의 디렉토리 내용보다 쉘 내 루프보다 우수합니다 .


디렉토리에 파일이 포함되어 있으면 작동하지 않는 것 같습니다.
user394

1
디렉토리 목록의 항목이 아니라 디렉토리의 inode를 참조하는 하드 링크에 관한 것입니다. 예를 들어, /some/directoryinode # 12345678이 있고 하위 디렉토리가없는 경우 해당 inode에 정확히 2 개의 하드 링크가 있습니다 : /some/directory/./some/directory. 디렉토리에 파일이 있는지 여부에 관계없이 작동합니다.
telcoM

BTRFS가 이와 관련하여 "일반 유닉스 파일 시스템"이 아니라는 점을 언급 할 가치가 있습니다. 불행히도 디렉토리는 항상 링크 수 1입니다. (그러나 .foo/..같은 아이 노드 번호가 않습니다.)
피터 코르에게

3

*/현재 디렉토리의 하위 디렉토리와 일치합니다. 여기에는 디렉토리에 대한 심볼릭 링크가 포함되어 있으며 원하는 디렉토리 일 수도 있습니다.

ksh93 ~(N)에서 패턴의 시작 부분에 추가 하면 일치하는 항목이 없으면 빈 목록으로 확장됩니다. 이를 사용하지 않으면 일치하는 항목이 없으면 패턴이 변경되지 않습니다.

다음 ksh93 함수는 서브 디렉토리를 포함하지 않거나 디렉토리에 링크 된 현재 디렉토리의 서브 디렉토리를 나열합니다.

list_leaf_directories () {
  local FIGNORE='.?(.)'        # don't ignore dot files
  local d
  for d in */; do
    [[ -L $d ]] || continue;   # skip symbolic links
    set -- ~(N)"$d"/*/
    if ((!$#)); then echo "$d"; fi
  done
done

0

내가 당신을 오해하지 않는다면, 당신은 하위 디렉토리가 아닌 디렉토리에서만 파일을 찾고 싶습니다. 이것이 당신의 의도라면, 여기 해결책이 있습니다.

find . -type f

일반 장치 이외의 파일 (블록 장치 파일, 문자 장치 파일 등)을 find찾으려면 명령에 대한 매뉴얼 페이지를 참조하고 해당 페이지 에서 type 키워드를 찾으십시오 . 일반 파일 및 디렉토리 등을 포함한 다른 파일 유형이 표시됩니다.

희망이 당신이 찾고있는 것입니다.


아뇨, 전혀 문제가 아닙니다. 일단 당신이 s / catalogue / directory / g를하면 분명하다. Nat Kup은 하위 디렉토리를 포함하지 않는 디렉토리를 찾고 있습니다.
Gilles 'SO- 악의를 멈춰라'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.