패턴과 일치하는 파일 이름이 포함된 디렉터리 이름을 나열하는 방법은 무엇입니까?

패턴과 일치하는 파일 이름이 포함된 디렉터리 이름을 나열하는 방법은 무엇입니까?

여러 하위 디렉터리와 파일이 포함된 디렉터리가 주어지면 정규식과 일치하는 파일 이름이 (직접 또는 간접적으로) 포함된 해당 디렉터리의 직접 하위 디렉터리 이름을 X나열하고 싶습니다 .X^rf.*\.img$

OS X에서 이를 달성하는 방법은 무엇입니까?

답변1

GNU를 사용하면 find각 디렉터리를 테스트할 수 있습니다.

for i in "$dir"/*/
do
    test -n "$(find "$i" -type f -regex '.*/test[^/]*' -print -quit)" \
       && echo "$i"
done

그러면 각 디렉터리에서 파일의 시작 부분을 검색 test하고 발견되면 해당 디렉터리를 인쇄합니다.

참고할 몇 가지 사항이 있습니다.

  1. ; 로 시작하는 하위 디렉터리를 무시합니다 . 이를 고려해야 하는 경우 Bash FAQ를 확인하여 .캡처하지 않고 포함하는 방법 .을 알아보세요 ...
  2. 우리는 게임이 있으면 find일찍 그만뒀다. -quit이렇게 하면 대규모 파일 시스템 트리에서 시간이 절약됩니다.
  3. 테스트는 -regex고려된 전체 경로 이름과 일치하므로 find기본 이름에 대해서만 일치하려는 경우 일치 시 주의해야 합니다 /. .-filename
  4. -iregex대소문자를 구분하지 않는 일치를 위해 대체를 사용할 수 있습니다 -regex.
  5. options 를 사용하여 정규식 구문을 선택할 수 있습니다 -regextype.

질문의 특정 패턴에 대해 와일드카드를 사용할 수 있으므로 다음과 같습니다.

for i in "$dir"/*/
do
    test -n "$(find "$i" -type f -name 'rf*.img' -print -quit)" && echo "$i"
done

답변2

( zsh이미 거기에 있다고 가정 X):

typeset -U subdirs
subdirs=(*/**/rf*.img(.e_'REPLY=${REPLY%%/*}'_))
print -rl -- "${subdirs[@]}"

이는 */**/rf*.img모든 하위 디렉터리의 모든 파일 rf*.img, glob 한정자를 glob .하고 e일반 파일만 선택하며 각각 고유 요소가 있는 배열로 정의된 배열(중복 없음)에 경로의 첫 번째 구성 요소만 저장합니다. 그런 다음 배열의 각 요소를 인쇄합니다.

답변3

다음을 사용하여 목록을 얻을 수 있습니다.find그리고 파이프를 통해grep:

(cd X && find . -type d -maxdepth 1 | sed -e 's,^./,,' | grep -E '^rf.*\.img$' )

나는 내부에 이름을 얻기 위해 서브쉘을 사용했습니다 X. 그렇지 않으면 경로를 고려해야 합니다 find.

반복적인 하위 디렉터리를 원하는 경우 이 -maxdepth 1옵션을 생략할 수 있습니다. 하지만 이는 정규식을 조정해야 함을 의미합니다.

(cd X && find . -type d | sed -e 's,^./,,' | grep -E '^(.*/)?rf.*\.img$' )

이 경우 sed 명령은 중복되지만 무해합니다.

답변4

사용 perl하고 grepglob.

#!/usr/bin/env perl
use strict;
use warnings;

my @file_list = grep { /^rf.*\.img$/ } glob "*";
print join ( "\n", @file_list );

또는 한 줄로:

perl -e 'print join ( "\n", grep { /^rf.*\.img$/ } glob "*" )'

참고 - glob쉘 스타일 와일드카드 확장을 수행하므로 glob "*/*/name/*"유사할 수 있습니다. 임의의 재귀 깊이가 필요한 경우 다음을 사용할 수 있습니다 File::Find.

#!/usr/bin/env perl
use strict;
use warnings;

use File::Find;

sub print_match {
    #Default match is against $_ which is filename. 
    #can match $File::Find::name for full name.
    #or $File::Find::dir
    print if  /^rf.*\.img$/;
}

find ( \&print_match, "/path/to/search" );

다시 한 문장으로 말하면:

perl -MFile::Find -e 'find ( sub { print if  /^rf.*\.img$/ }, "/my/path/to/search" );'

관련 정보