여러 하위 디렉터리와 파일이 포함된 디렉터리가 주어지면 정규식과 일치하는 파일 이름이 (직접 또는 간접적으로) 포함된 해당 디렉터리의 직접 하위 디렉터리 이름을 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
하고 발견되면 해당 디렉터리를 인쇄합니다.
참고할 몇 가지 사항이 있습니다.
- ; 로 시작하는 하위 디렉터리를 무시합니다 . 이를 고려해야 하는 경우 Bash FAQ를 확인하여
.
캡처하지 않고 포함하는 방법.
을 알아보세요..
. - 우리는 게임이 있으면
find
일찍 그만뒀다.-quit
이렇게 하면 대규모 파일 시스템 트리에서 시간이 절약됩니다. - 테스트는
-regex
고려된 전체 경로 이름과 일치하므로find
기본 이름에 대해서만 일치하려는 경우 일치 시 주의해야 합니다/
. .-filename
-iregex
대소문자를 구분하지 않는 일치를 위해 대체를 사용할 수 있습니다-regex
.- 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
하고 grep
그 glob
.
#!/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" );'