ls는 재귀적으로 전체 경로를 표시합니다.

ls는 재귀적으로 전체 경로를 표시합니다.

Linux에서 동일한 작업을 수행하는 방법은 분명히 여러 가지가 있지만 최근에는 for i in xxx트리의 각 항목 목록을 재귀적으로 탐색해야 했습니다. 을 tree수행하여 (또는 디렉토리 이름만 가져옴) tree -fail해결책을 찾았 tree -faild지만 다음과 같은 질문이 들었습니다. ls?

$ tree -fail
.
./.custom
./custom_loader.sh
./.git
./.git/branches
./.git/COMMIT_EDITMSG
./.git/config
./.git/description
./.git/HEAD
./.git/hooks
./.git/hooks/applypatch-msg.sample

답변1

쉘은 bash특별한 **글로빙 패턴을 통해 디렉토리로 재귀할 수 있습니다. 이 **패턴은 유사한 와 일치 *하지만 /경로 이름에도 걸쳐 있습니다.

shopt -s globstar nullglob dotglob

for dirpath in ./**/; do
    printf '%s\n' "$dirpath"
    # whatever other code needs to be run on "$dirpath"
done

액세스 권한 이 있고 globstar패턴이 일치하지 않으면 루프를 완전히 건너 **뛸 수 nullglob있으며 숨겨진 파일도 볼 수 있습니다.dotglob

이 패턴은 ./**/현재 디렉터리의 모든 디렉터리와 일치하는 것처럼 현재 디렉터리 내부 또는 아래의 모든 디렉터리와 일치합니다 ./*/.

모든 유형의 파일을 사용 ./**/*하거나 나열하십시오../**

다음 명령을 사용하여 이식 가능하게 이 작업을 수행할 수도 있습니다 find.

find . -type d -exec sh -c '
    for dirpath do
        printf "%s\n" "$dirpath"
        # whatever other code needs to be run on "$dirpath"
    done' sh {} +

여기에 스크립트 find의 루프 에 대한 sh -c디렉터리 경로 이름을 제공합니다.

이 두 예제를 실행할 때 볼 수 있는 유일한 차이점은 첫 번째 예제( bash루프 포함 **)가 디렉터리에 대한 심볼릭 링크가 find아닌 디렉터리에 대한 심볼릭 링크를 확인한다는 것입니다.

디렉토리만 나열하려는 경우 find예제를 다음과 같이 상당히 단축할 수 있습니다.

find . -type d -print

-type f대신 -type d일반 파일만 보려면 전체 삭제 테스트를 사용 하고, -type모든 유형의 파일을 보려면 전체 삭제 테스트를 사용하세요.

분명히 당신은 이와 같은 목록을 얻는 데 사용할 수도 있지만 ls나는 당신처럼 그것의 요점을 실제로 알지 못합니다.ls아무것도 할 수 없지만 출력을 보는 것 외에는 할 수 없습니다..

shopt -s globstar dotglob

ls -1d ./**

패턴이 확장되는 경로 이름 목록이 너무 길면 이 명령은 "인수 목록이 너무 김" 오류를 유발할 위험이 있습니다. 이 답변의 다른 명령에는 이 문제가 없습니다.

또한 ls여기에서는 실제로 재귀가 수행되지 않습니다. 오히려 쉘이 재귀 패턴을 확장하고 ./**호출 전에 인수 목록을 생성하기도 합니다.lsls

관련 정보