재귀 글로브?


80

다음과 같이 작성하고 싶습니다.

$ ls **.py

모든 .py 파일 이름을 얻으려면 디렉토리 계층 구조를 재귀 적으로 걸어 가십시오.

찾을 .py 파일이 있더라도 셸 (bash)은 다음과 같은 출력을 제공합니다.

ls: cannot access **.py: No such file or directory

내가 원하는 것을 할 수있는 방법이 있습니까?

편집 : 의 특정 경우에 관심이 없다는 것을 지정하고 싶지만 ls질문은 glob 구문에 관한 것입니다.

답변:


98

bash에서 재귀 글로브를 수행하려면 globstarbash 버전 4 이상의 기능 이 필요합니다 .

bash 맨 페이지에서 :

globstar
    If set, the pattern ** used in a pathname expansion context will
    match all files and zero or more directories and subdirectories.
    If the pattern is followed by a /, only directories and
    subdirectories match.

예제 패턴의 경우 :

shopt -s globstar
ls **/*.py

2
나는 가능도 권 해드립니다nullglob
글렌 잭맨

6
@glennjackman 그러나 활성화하기 전에 nullglob다음 경고를 읽는 것이 좋습니다.
Sroo Stroobandt 2018 년

2
^ 경고가 여기 로 이동 했습니다 .
usandfriends

1
bash 3.2를 사용하면 제대로 wc -l {**,.}/*.py작동합니다
Raphael

@Raphael 나는 릴리스 노트를 두 번 확인했으며 4.0에 도입되었다고 분명히 말합니다. 아마도 배포판에서 패치를 백 포트 했습니까? IIRC RHEL 5는 일부 기능을 백 포트했습니다. 또한 bash 4가 출시 된 지 9 년이 지났습니다.
jordanm

10
find . -name '*.py'

** 하나 이상의 작업을 수행하지 않습니다 * 모두 현재 디렉토리에서 작동합니다


흥미 롭군 그래도 구성 구문 (include 지시문)에서 사용해야하기 때문에 glob 구문 자체에 더 중점을 둡니다. 파일 목록이 필요하지 않습니다.
Paolo

2
@Doug O'Neal, 더 이상 사실이 아닙니다. bash는 이제 zsh 기능을 복사했습니다 (ksh93과 유사한 구문을 채택했지만 ksh와 유사하지만 zsh의 globbing 한정자를 지원하지는 않지만 유용성을 제한합니다)
Stéphane Chazelas

findbash 4가 없다면 할 수있는 일이 많이 있습니다 . 예 : yourcommand `find . -name '*.py'`(백틱 참고); find . -name '*.py' -exec yourcommand {} \;.
Mars

5

Bash 4 (zsh도 포함) 이후 패턴을 설정할 때 패턴을 다르게 처리 하는 새로운 글 로빙 옵션 ( globstar)이 추가되었습니다 **.

와일드 카드 패턴을 일치시키고 명령의 와일드 카드 패턴을 일치하는 항목으로 바꾸어 일치하는 파일 및 디렉토리 이름을 리턴합니다.

일반적으로을 사용할 때 **와 비슷하게 작동 *하지만 루프와 같이 모든 디렉토리를 재귀 적으로 재귀합니다.

활성화되어 있는지 확인하려면 shopt globstar(스크립팅에서)을 사용 하여 확인하십시오 shopt -q globstar.

이 예제 **.py는 재귀 할 수있는 디렉토리 목록을 리턴하지 않으므로 현재 디렉토리에서만 작동하므로 여러 디렉토리 레벨 와일드 카드를 사용해야 **/*.py하므로 더 깊이 들어갈 수 있습니다.

제발 SO에 찾아 내가 재귀 적으로 모든 파일을 찾기 위해 한 몇 가지 구문 테스트를.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.