주요한 -depth
것은 find
깊이 우선 검색을 수행하도록 합니다.
그러나 기본 순서는 다음과 같습니다.아니요너비 우선 검색.
기본 시퀀스는 "처리 노드의 깊이 우선 순회"로 비공식적으로 설명될 수 있습니다.첫 번째역추적 중에 그렇게 하는 대신에 발생했습니다. "
폭우우선탐색이 정말 필요해요. 어떻게 하면 find
이런 행동을 할 수 있을까요?
설명의 편의를 위해 다음 설정이 사용됩니다.
$ mkdir -p alpha/{bravo,charlie,delta}
$ touch alpha/charlie/{alpha,beta,gamma,phi}
find
다음과 같은 기본 동작이 있습니다.
$ find alpha
alpha
alpha/charlie
alpha/charlie/alpha
alpha/charlie/phi
alpha/charlie/beta
alpha/charlie/gamma
alpha/delta
alpha/bravo
및 -depth
다음과 같이 실행됩니다.
$ find alpha -depth
alpha/charlie/alpha
alpha/charlie/phi
alpha/charlie/beta
alpha/charlie/gamma
alpha/charlie
alpha/delta
alpha/bravo
alpha
그러나 내가 원하는 것은 다음과 같은 (가상) 옵션입니다.
$ find alpha -bfs
alpha
alpha/charlie
alpha/delta
alpha/bravo
alpha/charlie/alpha
alpha/charlie/phi
alpha/charlie/beta
alpha/charlie/gamma
즉, find
처리/보고 해야 합니다.모두추가 처리 전에 파일/디렉터리를 지정된 깊이에 배치합니다.
어떻게 해야 하나요?
답변1
# cat ./bfind
#!/bin/bash
i=0
while results=$(find "$@" -mindepth $i -maxdepth $i) && [[ -n $results ]]; do
echo "$results"
((i++))
done
이는 find
깊이와 반복을 추가하여 달성됩니다. 결과가 중복될 수 있지만 쉽게 필터링할 수 있다고 생각합니다.
답변2
쉘 와일드카드를 사용하면 간단히 이 작업을 수행할 수 있습니다. 점점 더 많은 디렉터리 수준으로 패턴을 구축하세요.
pattern='*'
set -- $pattern
while [ $# -ne 1 ] || [ "$1" != "$pattern" ]; do
for file; do
…
done
pattern="$pattern/*"
set -- $pattern
done
이렇게 하면 포인트 파일이 손실됩니다. 이를 포함 하려면 FIGNORE='.?(.)'
ksh, bash 또는 zsh shopt -s dotglob
에서 사용하십시오 .setopt glob_dots
지침:
- 파일이 많으면 메모리가 소모될 수 있습니다.
- 이는 디렉토리의 심볼릭 링크를 재귀적으로 순회합니다.
디렉터리와 디렉터리가 아닌 순서를 선택하고 성능이 중요하지 않은 경우 두 번의 패스를 만들고 [ -d "$file" ]
각 패스에서 테스트할 수 있습니다.
답변3
주로 경로 이름의 문자 find
수를 기준으로 정렬 하도록 파이프할 수 있습니다. /
예를 들어,
find alpha |
awk '{n=gsub("/","/",$0);printf "%04d/%s\n",n,$0}' |
sort -t/ |
sed 's|[^/]*/||'
awk
이는 경로 이름 앞에 슬래시 수를 추가하고 sed
끝에서 이 접두사를 제거하는 데 사용됩니다 .
실제로 디렉토리의 내용이 alpha/charlie+
나중에 나열되기를 원할 수도 있으므로 원하는 깊이를 alpha/charlie
지정해야 합니다 .sort -t/ -k1,1 -k2,2 -k3,3 -k4,4
답변4
파일을 찾고 속도보다는 순서에만 관심이 있는 경우(예: 대화형 프롬프트에 수천 개의 파일을 나열하는 경우) 다음과 같은 간단한 솔루션을 사용할 수 있습니다.
find -depth -type f | tac