단일 디렉토리 내의 모든 하위 디렉토리를 찾고 싶습니다. 이름 길이로 필터링해야 합니다. 나는 다음을 생각해 냈습니다.
find ./directory -maxdepth 1 -type d
이름 길이를 기준으로 결과를 필터링하려면 어떻게 해야 합니까? 예를 들어 4자보다 긴 하위 디렉터리만 필터링합니까?
답변1
?
와일드카드는 5번 사용할 수 있습니다 .
find ./directory -maxdepth 1 -type d -name '?????*'
이를 위해서는 이름에 5자 이상의 일치 항목이 필요합니다.
답변2
zsh
셸을 사용하면 파일 형식별로 glob을 필터링할 수 있습니다(여기목차) 사용글로벌 예선, extendedglob
해당 옵션을 켜면 (#cX,Y)
ERE 와 유사한 전역 연산자가 제공되므로 {X,Y}
다음을 수행할 수 있습니다.
set -o extendedglob
print -rC1 -- ?(#c5,)(ND/)
파일 print
r
유형 나열1
C
목차(glob 한정자)는 하나 이상의 문자( )로 구성됩니다 /
.5
?
?(#c5,12)
?(#c,5)
5~12자 또는 0~5자 입니다 ?(#c0,5)
(0자가 포함된 파일 이름을 얻을 수는 없음).
D
숨겨진 한정자를 무시하려면 한정자를 제거하세요.
glob 의 경우 zsh
문자로 디코딩할 수 없는 모든 바이트는 여전히 1로 간주됩니다(그리고 와 일치됩니다 ?
).
GNU 를 포함한 일부 find
구현 의 경우 find
, 적어도 GNU 시스템( fnmatch()
GNU libc의 GNU 정규식 사용)에서는 일치도 일치하지도 않습니다 ?
( *
regex .
). 따라서 다음 과 같습니다.
find . -maxdepth -name '?????*' -type d
또는
find . -maxdepth 1 -regextype posix-extended -regex '.*/[^/]{5,}' -type d
$'St\xe9phane'
예를 들어, UTF-8 로케일에서 실행 중인 경우 0xe9 바이트(ISO8859-1)를 문자로 디코딩할 수 없기 때문에 디렉터리를 일치시킬 수 없으며 é
실행 이외의 해결 방법은 없지만 바이트 길이로 계산됩니다. 성격이 아닙니다.find
LC_ALL=C
동등한 BSD 버전은 -regex
다음과 같습니다:
find -E . -maxdepth 1 -regex '.*/[^/]{5,}'
또는
find . -maxdepth 1 -regex '.*/[^/]\{5,\}'
(기본값은 기본 정규식이며 find
GNU의 경우 오래된 emacs 정규식 방언입니다.)
멀티바이트 문자 지원은 변형에 따라 다릅니다.
GNU 시스템의 경우 또 다른 접근 방식은 find
NUL로 구분된 파일 경로를 출력하고(NUL은 파일 경로에서 찾을 수 없는 유일한 문자이므로) gawk
이름 길이로 필터링하는 것입니다.
find . -mindepth 1 -maxdepth 1 -printf '%P\0' |
gawk -v RS='\0' -F/ 'length($NF) > 4'
문자로 디코딩할 수 없는 바이트가 있는 경우 경고가 발생 gawk
하지만, 각 바이트는 길이에 1을 기여합니다 zsh
.