유닉스-계열 및 일부 다른 운영 시스템에서, find는 사용자-지정된 기준에 따라 파일을 찾고 일치된 각 개체의 경로이름을 인쇄하거나, 또 다른 행위가 요청되면, 일치된 각 개체에 대해 해당 행위를 수행하는 명령줄 유틸리티입니다.
그것은 원하는 시작 위치에서 검색을 시작하고 그런-다음 계층 구조 (전형적으로 tree)의 노드 (디렉토리)를 재귀적으로 탐색합니다. find는 시작 디렉토리 아래에 마운트된 하나 이상의 저장 장치에 속하는 파티션의 다른 파일 시스템을 탐색하고 검색할 수 있습니다.
가능한 검색 기준은 파일이름과 일치시킬 패턴 또는 파일의 수정 시간 또는 접근 시간과 일치시킬 시간 범위를 포함합니다. 기본적으로, find는 현재 작업 디렉토리 아래의 모든 파일 목록을 반환하지만, 사용자는 시작 디렉토리 아래에서 원하는 최대 레벨의 숫자로 검색을 제한할 수 있습니다.
관련된 locate 프로그램은 find (전형적으로 cron 작업에 의해 정기적으로 업데이트됨)를 통해 얻은 색인화된 파일의 데이터베이스를 사용하여 전체 파일 시스템에서 이름으로 파일을 검색하는 더 빠른 방법을 제공합니다.
History
find는 Programmer's Workbench 프로젝트의 일부로 버전 5 유닉스에 나타났었고, 함께 사용하도록 설계된 cpio와 함께 Dick Haight에 의해 작성되었습니다.
GNU find 구현은 원래 Eric Decker에 의해 작성되었습니다. 그것은 나중에 David MacKenzie, Jay Plett 및 Tim Wood에 의해 향상되었습니다.
find 명령은 역시 IBM i 운영 시스템에 포팅되었습니다.
Find syntax
$ find [-H|-L] path... [operand_expression...]
두 가지 옵션은 find 명령이 심볼릭 링크를 처리해야 하는 방법을 제어합니다. 기본 동작은 심볼릭 링크를 따르지 않는 것입니다. -L 플래그는 find 명령에게 심볼릭 링크를 따르도록 하는 원인이 됩니다. -H 플래그는 명령줄 인수를 처리하는 동안 심볼릭 링크를 오직 따를 것입니다. 이들 플래그는 find에 대해 POSIX 표준에 지정되어 있습니다. 공통 확장은 -P 플래그로, 따르는 심볼릭 링크를 명시적으로 비활성화합니다.
적어도 하나의 경로가 표현 앞에 와야 합니다. find는 내부적으로 와일드카드를 해석할 수 있고 쉘 글로빙을 제어하기 위해 명령을 주의해서 인용해야 합니다.
표현식 요소는 명령줄 인수 경계로 구분되며, 보통 쉘 구문에서 공백으로 표시됩니다. 그것들은 왼쪽에서 오른쪽으로 평가됩니다. 그것들은 AND(-and 또는 -a) 및 OR (-or -o)와 같은 논리적 요소와 술어 (필터 및 행위)를 포함할 수 있습니다.
GNU find는 POSIX에서 지정되지 않은 많은 추가적인 특색을 가집니다.
Predicates
공통적으로-사용된 기본은 다음을 포함합니다:
- -name pattern - 파일 이름이 주어진 shell-glob 패턴과 일치하는지 테스트합니다.
- -type type - 파일이 주어진 유형인지 테스트합니다. 허용된 유닉스 파일 형식은 다음을 포함합니다:
- b - 블록 디바이스 (버퍼된 것);
- c - 문자 디바이스 (버퍼되지 않은 것);
- d - 디렉토리;
- f - 정규 파일;
- l - 심볼릭 링크;
- p - 이름-지어진 파이프;
- s - 소켓;
- D - door.
- -print - 항상 참을 반환합니다; 현재 파일의 이름과 표준-출력에 줄 바꿈을 인쇄합니다.
- -print0 - 항상 참을 반환합니다; 현재 파일의 이름과 null 문자를 표준-출력에 인쇄합니다. POSIX에서는 요구되지 않습니다.
- -exec program [argument ...]; - 항상 참을 반환합니다. 주어진 고정 인수와 파일의 현재 경로로 프로그램을 실행합니다.
- -exec program [argument ...] {} + - 항상 참을 반환합니다. 주어진 고정 인수와 가능한 한 많은 경로로 프로그램을 실행합니다 (xargs와 같은 최대 명령줄 크기까지). 대부분의 구현에 대해, {}의 추가적인 발생은 지정된 이름의 추가적인 사본을 의미합니다 (POSIX에 의해 요구되지 않은 특색).
- -ok program [argument ...]; - -exec와 같지만, 프로그램이 0을 반환하지는 여부에 따라 참 또는 거짓을 반환합니다.
만약 표현이 -print0, -print, -exec, 또는 -ok 중 어떤 것도 사용하지 않으면, find는 조건이 참으로 테스트되면 기본적으로 -print를 수행합니다.
Operators
연산자는 find 명령의 표현을 향상시키기 위해 사용될 수 있습니다. 연산자는 우선 순위가 낮은 순서로 나열됩니다:
- ( expr ) - 강제 우선권;
- ! expr - expr이 거짓이면 참입니다;
- expr1 expr2 (또는 expr1 -a expr2) - AND. expr2는 expr1이 거짓이면 평가되지 않습니다;
- expr1 -o expr2 - OR. expr2는 expr1이 참이면 평가되지 않습니다.
$ find . -name 'fileA_*' -o -name 'fileB_*'
이 명령은 이름이 "fileA_" 또는 "fileB_"로 시작하는 파일에 대해 현재 작업 디렉토리 트리를 검색합니다. 우리는 쉘이 확장하지 않도록 fileA_*를 인용합니다.
$ find . -name 'foo.cpp' '!' -path '.svn'
이 명령은 이름이 "foo.cpp"인 파일에 대해 하위 디렉토리 트리 ".svn"을 제외한 현재 작업 디렉토리 트리를 검색합니다. 우리는 쉘에 의해 역사 대체 문자로 해석하지 않도록 !을 인용합니다.
POSIX protection from infinite output
실제 파일 시스템은 종종 하드 또는 소프트 링크의 사용을 통해 생성된 루프된 구조를 포함합니다. POSIX 표준은 다음을 요구합니다:
find 유틸리티는 무한 루프를 감지해야 합니다; 즉, 마지막으로 발견된 파일의 조상인 이전에 방문한 디렉토리를 입력하는 것입니다. 그것이 무한 루프를 감지할 때, find는 표준 오류에 진단 메시지를 작성해야 하고 계층 구조에서 위치를 복구하거나 종료해야 합니다.
Examples
From the current working directory
$ find . -name 'my*'
이것은 이름이 my로 시작하는 파일에 대해 현재 작업 디렉토리 트리를 검색합니다. 단일 따옴표는 쉘 확장을 방지합니다–그것없이 쉘은 현재 작업 디렉토리에서 이름이 my로 시작하는 파일의 목록으로 my*를 대체합니다. 더 최신 버전의 프로그램에서, 디렉토리는 생략될 수 있고, 그것은 현재 작업 디렉토리를 의미할 것입니다.
Regular files only
$ find . -name 'my*' -type f
이것은 위의 검색 결과를 오직 정규 파일로 제한하며, 따라서 디렉토리, 특수 파일, 심볼릭 링크 등은 제외됩니다. my*는 단일 따옴표 (아포스트로피)로 묶여 있는데 왜냐하면 그렇지 않으면 쉘이 my...로 시작하는 현재 파일의 목록으로 그것을 대체하기 때문입니다.
Commands
이전 예제는 기본적으로 find가 -print 동작을 실행하기 때문에 결과의 목록화를 생성했습니다. (초기 버전의 find 명령은 기본 동작을 전혀 가지지 않음을 주목하십시오; 따라서 결과 파일의 목록이 삭제되어 사용자를 당황하게 했습니다.)
$ find . -name 'my*' -type f -ls
이것은 확장된 파일 정보를 인쇄합니다.
Search all directories
$ find / -name myfile -type f -print
이것은 이름이 myfile인 정규 파일을 모든 각 디렉토리에서 검색하고 그것을 화면에 인쇄합니다. 일반적으로 이런 방식으로 파일을 찾는 것은 좋지 않습니다. 이것은 상당한 시간이 소요될 수 있으므로, 디렉토리를 보다 정확하게 지정하는 것이 가장 좋습니다. 일부 운영 시스템은 find에 적합하지 않은 동적 파일 시스템을 마운트할 수 있습니다. 쉘에 특별한 문자를 포함하는 더 복잡한 파일이름은 단일 따옴표로 묶어야 필요가 있을 것입니다.
Search all but one subdirectory tree
$ find / -path excluded_path -prune -o -type f -name myfile -print
이것은 이름이 myfile인 정규 파일에 대해 -prune 동작에 의해 정리되는 하위 디렉토리 트리 included_path (선행하는 /를 포함한 전체 경로)를 제외한 모든 각 디렉토리를 검색합니다.
Specify a directory
$ find /home/weedly -name myfile -type f -print
이것은 /home/weedly 디렉토리 트리에서 myfile이라는 정규 파일을 검색합니다. 항상 기억할 수 있는 가장 깊은 수준으로 디렉토리를 지정해야 합니다.
Search several directories
$ find local /tmp -name mydir -type d -print
이것은 현재 작업 디렉토리의 local 하위디렉토리 트리와 mydir이라는 디렉토리에 대한 /tmp 디렉토리 트리를 검색합니다.
Ignore errors
만약 루트가 아닌 다른 사용자로 이 작업을 수행하면, 권한 거부 (및 임의의 다른) 오류를 무시하기를 원할 수 있습니다. 오류는 표준-오류에 인쇄되므로, 그것들은 출력을 /dev/null로 리다이렉션함으로써 표시되지 않을 수 있습니다. 다음 예제는 bash 쉘에서 이것을 수행하는 방법을 보여줍니다:
$ find / -name myfile -type f -print 2> /dev/null
만약 csh 또는 tcsh 사용자이면, 표준-출력도 리다이렉션하지 않고 표준-오류를 리다이렉션할 수 없습니다. 여러분은 이 문제를 해결하기 위해 find 명령을 실행하기 위해 sh를 사용할 수 있습니다:
$ sh -c "find / -name myfile -type f -print 2> /dev/null"
csh 또는 tcsh를 사용할 때 대안적인 방법은 표준-출력 및 표준-오류의 출력을 grep 명령으로 파이프하는 것입니다. 이 예제는 권한 거부 오류를 포함하는 행을 표시하지 않는 방법을 보여줍니다.
$ find . -name myfile |& grep -v 'Permission denied'
Find any one of differently named files
$ find . \( -name '*jsp' -o -name '*java' \) -type f -ls
-ls 연산자는 확장된 정보를 인쇄하고, 그 예제는 이름이 'jsp' 또는 'java'로 끝나는 임의의 정규 파일을 찾습니다. 괄호는 필수 항목임을 주목하십시오. 많은 쉘에서 괄호는 특수 쉘 문자로 해석되지 않도록 백슬래시 (\( 및 \))로 이스케이프되어야 합니다. -ls 연산자는 모든 버전의 find에서 사용할 수 없습니다.
Execute an action
$ find /var/ftp/mp3 -name '*.mp3' -type f -exec chmod 644 {} \;
이 명령은 디렉토리 트리 /var/ftp/mp3에서 이름이 .mp3로 끝나는 모든 정규 파일의 허가권을 변경합니다. 동작은 명령에서 문장 -exec chmod 644 {} \;을 지정함으로써 수행됩니다. 이름이 .mp3로 끝나는 모든 정규 파일에 대해, 명령 chmod 644 {}가 {}를 파일 이름으로 대체하여 실행됩니다. 세미콜론 (쉘이 명령 구분-기호로 해석하지 않도록 백슬래시됨)은 명령의 끝을 나타냅니다. 보통 rw-r--r--로 표시되는 허가권 644는 파일 소유자에게 파일을 읽고 쓸 수 있는 전체 권한을 부여하지만, 다른 사용자는 읽기-전용 접근 권한을 가집니다. 일부 쉘에서, {}는 단일 따옴표로 묶여야 합니다. 후행하는 ";"는 관례적으로 선행하는 "\"로 인용되지만, 단일 따옴표로 효과적으로 묶을 수 있습니다.
명령 자체는 인용해서는 인용 부호로 묶어서는 안됨을 주목하십시오; 그렇지 않으면 다음과 같은 오류 메시지를 만날 것입니다:
find: echo "mv ./3bfn rel071204": No such file or directory
이것은 find가 'echo "mv ./3bfn rel071204"'라는 파일을 실행하려고 시도했고 실패했음을 의미합니다.
만약 많은 결과에 대해 실행될 것이면, ARG_MAX까지 파일이름을 수집하고 그런-다음 파일이름 목록과 함께 COMMAND를 실행하는 exec 기본 변형을 사용하는 것이 더 효율적입니다.
$ find . -exec COMMAND {} +
이것은 공백을 갖는 파일이름이 쉘에 의해 분할되지 않고 실행된 COMMAND에 전달되는 것을 보장합니다.
Delete files and directories
-delete 동작은 GNU 확장이고, 이를 사용하면 -depth가 켜집니다. 따라서, -delete 대신 -print와 함께 find 명령을 테스트하여 그것을 수행하기 전에 어떤 일이 발생하는지 파악하려면, -depth -print를 사용해야 합니다.
빈 파일을 삭제하고 이름을 인쇄하십시오 (-empty는 모든 find 구현에서 사용 가능하지 않을 수 있는 GNU find에서 공급업체 고유 확장입니다):
$ find . -empty -delete -print
빈 정규 파일을 삭제합니다:
$ find . -type f -empty -delete
빈 디렉토리를 삭제합니다:
$ find . -type d -empty -delete
'bad'로 이름-지어진 빈 파일을 삭제합니다:
$ find . -name bad -empty -delete
경고 — -delete 동작은 -empty 또는 -name과 같은 조건과 함께 사용되어야 합니다:
$ find . -delete # this deletes all in .
Search for a string
이 명령은 /tmp 디렉토리 트리에서 모든 파일에서 문자열을 검색합니다:
$ find /tmp -type f -exec grep 'search string' /dev/null '{}' \+
/dev/null 인수는 찾은 텍스트 앞에 파일 이름을 표시하기 위해 사용됩니다. 그것 없이, 오직 찾은 텍스트가 인쇄됩니다. GNU grep은 자체로 이 임무를 수행하기 위해 사용될 수 있습니다:
$ grep -r 'search string' /tmp
jsmith의 홈 디렉토리 트리에서 "LOG"를 검색하는 예제:
$ find ~jsmith -exec grep LOG '{}' /dev/null \; -print
/home/jsmith/scripts/errpt.sh:cp $LOG $FIXEDLOGNAME
/home/jsmith/scripts/errpt.sh:cat $LOG
/home/jsmith/scripts/title:USER=$LOGNAME
현재 작업 디렉토리 트리의 모든 XML 파일에서 "ERROR" 문자열 검색의 예제:
$ find . -name "*.xml" -exec grep "ERROR" /dev/null '{}' \+
검색 문자열을 묶는 이중 따옴표(" ")와 중괄호를 묶는 단일 따옴표 (' ')는 이 예제에서 선택 사항이지만, 문자열에 공백과 기타 특수 문자를 허용하기 위해 필요합니다. 더 복잡한 텍스트와 함께 (특히 `sh` 및 `csh`에서 파생된 가장 인기 있는 셸에서) 이중 따옴표가 모든 특수 해석을 방해하지 않기 때문에 단일 따옴표가 종종 더 쉬운 선택임을 주목하십시오. 영어로 축약된 파일 이름을 인용 부호로 묶으면 이것이 얼마나 복잡해질 수 있는지 보여주는데, 왜냐하면 그 안에 아포스트로피가 있는 문자열은 이중 따옴표로 보호하는 것이 더 쉽기 때문입니다:
$ find . -name "file-containing-can't" -exec grep "can't" '{}' \; -print
Search for all files owned by a user
$ find . -user <userid>
Search in case insensitive mode
-iname은 표준에 있지 않고 모든 구현에서 지원되는 것은 아님을 주목하십시오.
$ find . -iname 'MyFile*'
만약 -iname 스위치가 시스템에서 지원되지 않으면 다음과 같은 해결 방법이 가능할 수 있습니다:
$ find . -name '[mM][yY][fF][iI][lL][eE]*'
이것은 Perl을 위의 명령을 빌드하기 위해 사용합니다 (일반적으로 이러한 종류의 사용은 위험한데, 왜냐하면 특수 문자가 `sh`의 표준 입력에 공급되기 전에 제대로 묶이지 않기 때문입니다):
$ echo 'MyFile*' | perl -pe 's/([a-zA-Z])/[\L\1\U\1]/g;s/(.*)/find . -name \1/' | sh
Search files by size
크기가 100 킬로바이트에서 500 킬로바이트 사이인 파일을 검색하기:
$ find . -size +100k -a -size -500k
빈 파일을 검색하기:
$ find . -size 0k
비-빈 파일을 검색하기:
$ find . ! -size 0k
Search files by name and size
$ find /usr/src ! \( -name '*,v' -o -name '.*,v' \) '{}' \; -print
이 명령은 /usr/src 디렉토리 트리를 검색할 것입니다. '*,v' 및 '.*,v' 형식인 모든 파일은 제외됩니다. 참고해야 할 중요한 인수는 마우스-오버 시 표시되는 도구 설명에 있습니다.
for file in `find /opt \( -name error_log -o -name 'access_log' -o -name 'ssl_engine_log' -o -name 'rewrite_log' -o
-name 'catalina.out' \) -size +300000k -a -size -5000000k`; do
cat /dev/null > $file
done
단위는 [bckw] 중 하나여야 하며, 'b'는 512바이트 블록, 'c'는 바이트, 'k'는 킬로바이트, 'w'는 2바이트 단어를 의미합니다. 크기는 간접 블록을 계산하지 않지만, 실제로 할당되지 않은 흩어져있는 파일의 블록을 계산합니다.
Related utilities
- locate는 파일 시스템의 디렉토리 트리 대신 미리-작성된 파일의 데이터베이스를 검색하는 유닉스 검색 도구입니다. 이것은 find보다 더 빠르지만 덜 정확한데 왜냐하면 데이터베이스가 최신 상태가 아닐 수 있기 때문입니다.
- grep는 일반 텍스트 데이터 집합에서 정규식과 일치하는 행을 검색하고 기본적으로 표준 출력에서 일치하는 행을 보고하는 명령줄 유틸리티입니다.
- tree는 디렉토리 트리에서 찾은 파일을 재귀적으로 나열하는 명령줄 유틸리티로, 파일 계층 구조에서의 위치에 따라 파일 이름을 들여씁니다.
- GNU Find Utilities (역시 findutils로 알려져 있음)은 도구 find와 xargs의 구현을 포함하는 GNU 패키지입니다.
- BusyBox는 리소스가 매우 제한된 임베디드 운영 시스템을 위한 단일 실행 파일에 여러 가지 제거된 유닉스 도구를 제공하는 유틸리티입니다. 그것은 역시 find의 버전을 제공합니다.
- dir은 파일 또는 디렉토리를 재귀적으로 검색하는 /s 옵션을 가집니다.
- Plan 9 from Bell Labs는 find를 대체하는 두 가지 유틸리티를 사용합니다: 오직 트리를 탐색해서 이름을 인쇄하는 walk 및 오직 쉘 스크립트의 형식에서 표현식을 평가함으로써 (grep와 같은) 걸러내는 sor. 임의의 필터는 파이프를 통해 사용될 수 있습니다. 그 명령은 Plan 9 from User Space의 일부가 아니므로, 구글의 Benjamin Barenblat에는 GitHub를 통해 사용할 수 있는 POSIX 시스템으로 이식된 버전이 있습니다.
- fd는 Rust programming language로 쓰인 find의 단순한 대안입니다.