여러 패턴과 일치하는`find -name` 패턴


335

명령을 사용하여 디렉토리에있는 모든 파이썬 및 HTML 파일 목록을 가져 오려고했습니다 find Documents -name "*.{py,html}".

그런 다음 맨 페이지가 나왔습니다.

패턴 내의 중괄호 ( '{}')는 특수한 것으로 간주되지 않습니다 (즉, find. -name 'foo {1,2}'는 foo1 및 foo2 파일이 아니라 foo {1,2}라는 파일과 일치합니다.

이것이 파이프 체인의 일부이므로 런타임에 일치하는 확장명을 지정할 수 있기를 원합니다 (하드 코딩 없음). 만약 그것을 찾을 수 없다면, perl one-liner (또는 이와 유사한)가 좋습니다.

편집 : 결국 내가 찾은 대답에는 모든 종류의 쓰레기가 포함되어 있으며 조금 길기 때문에 처음에 가려운 원래 가려움증에 대한 답변 으로 게시했습니다 . 더 나은 솔루션이 있다면 자유롭게 해킹하십시오.



locate내부 업데이트가 최신 상태가 아닐 수도 있다는 경고에도 불구하고 종종 간과되고 사용 되지 않는 유틸리티도 있습니다. 그러나 빠릅니다.
michael

나는 유닉스와 리눅스에 속해 있기 때문에이 질문을
논외

답변:


481

-o"또는"을 의미 하는를 사용하십시오 .

find Documents \( -name "*.py" -o -name "*.html" \)

프로그래밍 방식으로 해당 명령 줄을 작성해야합니다. 쉽지 않습니다.

bash (또는 Windows의 Cygwin)를 사용하고 있습니까? 당신이 있다면, 당신은 이것을 할 수 있어야합니다 :

ls **/*.py **/*.html

프로그래밍 방식으로 빌드하기가 더 쉬울 수 있습니다.


3
나는 일반적으로 모든 bashism과 더 많은 것을 지원하는 zsh를 사용하고 있습니다.
Xiong Chiamiov

12
Zsh는 **재귀 검색을 지원합니다 . Bash는 버전 4.0 이상에서만 지원합니다 shopt -s globstar.
ephemient

2
얼마나 많은 -o arg를 가질 수 있습니까? 나는 .gcda (보도 자료)의 가능성이 큰 목록을 가지고 구축 할 파일을 한
재스퍼 블루스

40
-name사용하는 경우 두 개의 괄호로 묶어야 -exec합니다. 예find Documents \( -name "*.py" -o -name "*.html" \) -exec file {} \;
artbristol

2
예를 들어 -print0공백이있는 파일 이름을 처리하기 위해 a 를 추가하는 경우 @artbristol 주석은 매우 관련 이 있습니다.
nimrodm

63

대부분 리눅스 시스템에서 발견 된 일부 에디션은 정규식과 일치하는 이름을 가진 파일을 찾는 -regex 및 -regextype 옵션도 지원합니다.

예를 들어

find . -regextype posix-egrep -regex ".*\.(py|html)$" 

위의 예에서 트릭을 수행해야합니다. 그러나 이것은 표준 POSIX 찾기 기능이 아니며 구현에 따라 다릅니다.


1
다른 답변보다 더 복잡하지만 더 복잡한
m1k3y3

12
더 간단 : find . -regex ".*\.\(py\|html\)$"find는 기본적으로 Emacs 스타일의 정규 표현식으로 약간 다르기 때문에 작동하므로 regextype을 지정할 필요가 없습니다.
robru

2
많은 표현 -regextype posix-egrep이 있으면 편리합니다 (그렇지 않으면 많은 문자를 피해야합니다). 이것은 Windows 배포 zip을 구축하는 dist-hook에 사용한 find 명령입니다 (파일을 변경하고 파일 내에서 파일을 dos-eol로 변경 함). find -regextype posix-egrep -regex ".*(\.([chyl]|def|cpy|cob|conf|cfg)|(README|ChangeLog|AUTHORS|ABOUT-NLS|NEWS|THANKS|TODO|COPYING.*))$" -exec sed -i -e 's/\r*$/\r/' {} \;
Simon Sobisch

32

다음 -name과 같이 구분하여 프로그래밍 방식으로 더 많은 절을 추가 할 수 있습니다 -or.

find Documents \( -name "*.py" -or -name "*.html" \)

또는 간단한 루프를 대신 사용하십시오.

for F in Documents/*.{py,html}; do ...something with each '$F'... ; done

@ user2284570 : 그런 다음 *.py파일이 없거나 이상한 버전이 find있습니다. 위에 나열된 명령은 정상적으로 작동합니다.
Stephan202

아니요,을 사용하고 -iname있습니다. *.py파일을 마지막 위치에 쓰는 경우에만 파일을 반환 합니다 ( iname *.html첫 번째 표현식도 마찬가지 입니다) . 데비안에서 명령을 사용합니다.
user2284570

따옴표를 사용하고 있습니까? 매우 중요합니다.
Stephan202

1
-또는 -o입니까?
Stephane

1
@StephaneEybert : 어느 쪽이든 괜찮지 만 후자는 POSIX 호환입니다 (man page에 따르면).
Stephan202

16

이것은 리눅스에서 모든 .c 또는 .cpp 파일을 찾을 것입니다

$ find . -name "*.c" -o -name "*.cpp"

추가 모드를 수행하지 않으면 이스케이프 처리 된 괄호가 필요하지 않습니다. 여기 맨 페이지에서 패턴이 일치하면 인쇄합니다. 아마도 그들은 인쇄를 제어하려고합니다. 이 경우 -print는 조건부 역할을하며 "AND'd"조건부가됩니다. .c 파일이 인쇄되지 않습니다.

$ find .  -name "*.c" -o -name "*.cpp"  -print

그러나 원래의 답변을 좋아한다면 인쇄를 제어 할 수 있습니다. 모든 .c 파일도 찾을 수 있습니다.

$ find . \( -name "*.c" -o -name "*.cpp" \) -print

모든 c / c ++ 소스 파일에 대한 마지막 예

$ find . \( -name "*.c" -o -name "*.cpp"  -o -name "*.h" -o -name "*.hpp" \) -print

11

나는 비슷한 필요성이 있었다. 이것은 나를 위해 일했다 :

find ../../ \( -iname 'tmp' -o -iname 'vendor' \) -prune -o \( -iname '*.*rb' -o -iname '*.rjs' \) -print

3
완전한. 그러나 나는 그것이 작동하지 않는 것이 조금 이상하다는 것을 ()
알았

* .c * .cpp 또는 * .cc와 일치하는 파일을 찾고 싶었습니다. 두 개의 이름 패턴 만 있으면 괄호가 필요하지 않지만 세 개의 이름 패턴은 두 개의 -o 패턴과 합쳐져서 find -name "*.cpp" -o -name "*.c" -o -name "*.cc" -print0한 쌍의 괄호를 사용해야했습니다 두 번째 또는 연산자를 그룹화하십시오. find -name "*.cpp" -o \( -name "*.c" -o -name "*.cc" \) -print0항상 "true"인 -print0이 논리에 영향을 줄 수 있습니다.
카디프 우주 남자

5

내 기본값은 다음과 같습니다.

find -type f | egrep -i "*.java|*.css|*.cs|*.sql"

findBrendan Long과 Stephan202 등의 적은 프로세스 의도 실행 과 같이 :

find Documents \( -name "*.py" -or -name "*.html" \)


3
그것은 egrep정규 표현식을 올바르게 사용하는 것이 아니라 정규 표현식을 사용해야하는 쉘 글로브입니다. (또한, 일반 find: 사용법은 find {directory} [options...] [action], 어디서, IMPL에 따라 directory기본적 수 .action기본값으로 -print그래서, 대신, 사용과 같은,하지만 난 명시 수 있습니다.) find . -type f -print | egrep -i '\.java$|\.css$|\.cs$|\.sql$' 그러나 또한, 같은 정말 빨리 대안에 find, 하나는 수도 locate비슷한 방식으로 시도해보십시오 (파일 목록에 대해 내부 db를 쿼리하기 때문에 반드시 최신 상태는 아니지만)
michael

2
#! /bin/bash
filetypes="*.py *.xml"
for type in $filetypes
do
find Documents -name "$type"
done

간단하지만 작동 :)


1

일부 파일을 제외하고 하위 디렉토리의 모든 파일을 제거해야했습니다. 다음은 나를 위해 일했습니다 (세 가지 패턴 지정).

find . -depth -type f -not -name *.itp -and -not -name *ane.gro -and -not -name *.top -exec rm '{}' +

1

패턴 내 괄호는 다음 \(\)과 같은 이름 패턴에 필요합니다.or

find Documents -type f \( -name "*.py" -or -name "*.html" \)

and연산자가 있는 이름 패턴 에는 필요하지 않지만

find Documents -type f ! -name "*.py" -and ! -name "*.html" 

0

이것은 AIX korn 쉘에서 작동합니다.

find *.cbl *.dms -prune -type f -mtime -1

이 찾고있는 *.cbl또는 *.dms하위 디렉토리를 건너 뛰는 만 현재 디렉토리에, 일일 나이가있다.


0
find MyDir -iname "*.[j][p][g]"
+
find MyDir -iname "*.[b][m][p]"
=
find MyDir -iname "*.[jb][pm][gp]"

2
후자는 foo.jmg와 일치하지만 상위 2 개는 일치하지 않습니다.
copper.hat

0

이건 어떤가요

ls {*.py,*.html}

파일 이름에 .py 또는 .html로 끝나는 모든 파일을 나열합니다.

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