find: 이름에 숫자가 있는 디렉토리와 하위 디렉토리를 제외한 모든 디렉토리를 나열합니다.

find: 이름에 숫자가 있는 디렉토리와 하위 디렉토리를 제외한 모든 디렉토리를 나열합니다.

숫자가 없는 모든 디렉터리(원래 경로 제외)를 찾으려면 다음 명령을 실행합니다.

find /path/2/directory -type d -name '[!0-9]*'

문제는 찾은 디렉토리가 해당 번호의 디렉토리의 하위 디렉토리라는 것입니다.

예:

/path/2/directory/20160303/backup

심지어

/path/2/directory/backup20160303a/backup

find가 그러한 디렉토리를 반환하는 것을 방지할 수 있는 방법이 있습니까?

깊이를 제한하는 것만으로는 이 문제를 해결할 수 없습니다. 깊이는 다양할 수 있습니다.

예:

/path/2/directory/subdirectory/20160303/backup

답변1

-prune다음 디렉토리를 무시 하는 데 사용됩니다 .

find /path/to/directory -name '*[0-9]*' -prune -o -type d -print

그러나 gnu이를 설정 하는 경우 C위 명령을 실행할 때 로케일을 사용하는 것이 좋습니다. 아래 Stéphane의 설명을 참조하세요.

답변2

find가 특정 일치 항목 이상으로 떨어지지 않도록 하려면 예를 들어 with 의 출력을 -prune필터링하는 대신 and를 사용해야 합니다.-pathfindgrep -v

find테스트를 위해 원치 않는 자료가 표시되지 않는지 확인할 수 있도록 추가 파일과 하위 디렉터리가 있는 환경을 만듭니다 .

mkdir -p tmp/2/abc/def
touch tmp/2/abc/def/file1
mkdir -p tmp/2/abc/9876/xyz
touch tmp/2/abc/9876/xyz/file2
tree tmp/

다음을 제공합니다:

tmp
└── 2
    └── abc
        ├── 9876
        │   └── xyz
        │       └── file2
        └── def
            └── file1

find tmp/2/abc \! -path "*[0-9]*"@terdon의 제안을 따르면 아래에서 시작하는 디렉토리뿐만 아니라 전체 경로도 고려되므로 출력이 비어 -path있게 abc됩니다 2.

@cas가 제안한 대로 이 작업을 수행 하면 find tmp/2/abc -type d | grep -vE '/[0-9-]+(/|$)'검색 중인 파일과만 일치하는 것이 아니라 이름이 지정된 디렉터리와도 일치하므로 아무것도 인쇄되지 않는다는 것을 알게 될 것입니다 2. 무엇보다도 먼저 전체 트리를 순회하려면 find가 필요하며 9876, 거기에 수십만 개의 항목이 있는 경우 순회(및 필터링)에 많은 시간이 걸립니다.

이렇게 하면:

find tmp/2/abc -type d -name '[!0-9]*' -print 

출력에 path 가 포함되어 있음을 알 수 있습니다 tmp/2/abc/9876/xyz. 그것을 제거하려면 원하지 않는 것을 잘라내십시오 -prune.

find tmp/2/abc -type d -name '[!0-9]*' -print -o -name '[0-9]*' -prune

이것은 만든다:

tmp/2/abc
tmp/2/abc/def

@don_cristti가 이 답변을 향상시키기 위해 수행한 작업인 트림과 인쇄를 교체하여 효율성을 약간 향상시킬 수 있습니다.

답변3

나는 당신이 찾고 있다고 생각합니다 -path:

   -path pattern
          File  name matches shell pattern pattern.  The metacharacters do
          not treat `/' or `.' specially; so, for example,
                    find . -path "./sr*sc"
          will print an entry for a directory called `./src/misc' (if  one
          exists).  

주어진 패턴에 대해 각 파일/디렉토리의 전체 경로를 검색합니다. 따라서 다음과 같은 디렉토리 구조가 있는 경우:

$ tree
.
├── 111
│   └── foo
│       └── bar
├── bar
│   └── foo
│       └── baz
└── foo
    └── 111
        └── bar

9 directories, 0 files

다음과 같이 사용할 수 있습니다 find.

$ find /path/to/directory/ \! -path "*[0-9]*" 
.
./foo
./bar
./bar/foo
./bar/foo/baz

또는 GNU를 사용하십시오 find.

find /path/to/directory/ -not -path "*[0-9]*" 

이는 이름을 확인하기 위해 각 디렉터리를 드릴다운해야 하기 때문에 큰 디렉터리 트리보다 큰 디렉터리 트리에서 훨씬 느립니다.@Anthon의 솔루션자두와 함께. 그러나 수천 개의 디렉토리가 없어도 괜찮습니다.

답변4

grep(또는 또는 등)을 사용하여 awk출력 sed에서 perl​​이러한 디렉터리를 쉽게 제거할 수 있습니다 .find

find /path/to/directory -type d | grep -vE '/[0-9-]+(/|$)'

-참고: 날짜가 포함된 디렉토리가 때때로 YYYYMMDD가 아닌 YYYY-MM-DD이기 때문에 이를 문자 클래스에 포함했습니다 .

관련 정보