find 명령어 리눅스: 이름, 크기, 날짜로 파일 찾기 예제
find 명령어는 디렉터리 트리를 훑으며 조건에 맞는 파일을 찾습니다. find /path -name '*.log'은 이름으로, -type f는 파일만, -size +100M은 100MB보다 큰 파일, -mtime -7은 최근 일주일 안에 수정된 파일을 찾습니다. 조건을 조합하고, 찾은 파일에 -exec나 -delete를 적용하거나 xargs로 목록을 넘길 수 있습니다.
find는 디렉터리 트리를 따라 내려가며 이름, 종류, 크기, 수정 날짜, 소유자, 권한 같은 조건으로 파일을 찾습니다. 기본 형식은 find [어디서] [조건] [동작]입니다. 아래에서는 설정 파일 찾기, 오래된 로그 정리, 디스크를 차지하는 대용량 파일 찾기 같은 실무 과제에 맞춘 find 리눅스 예제를 정리했습니다.
find 명령어의 기본 구조
find /var/log -type f -name '*.log' -mtime +30 -print
구성 요소를 하나씩 보겠습니다.
/var/log는 검색을 시작할 위치입니다. 여러 경로를 나열하거나.(현재 디렉터리)을 쓸 수도 있습니다. 경로를 생략하면 GNU find는 현재 디렉터리에서 검색합니다.-type f -name '*.log' -mtime +30은 조건들입니다. 문서에서는 이를 테스트라고 부릅니다. 조건 사이에는 기본적으로 논리 "그리고(AND)"가 적용됩니다.-print는 동작으로, 경로를 출력합니다. 다른 동작을 지정하지 않으면 자동으로 적용됩니다.
find는 하위 디렉터리까지 재귀적으로 들어갑니다. 일반 사용자가 시스템 경로를 검색하면 Permission denied 메시지가 쏟아질 수 있습니다. 오류 출력을 버리면 깔끔해집니다.
find / -name 'nginx.conf' 2>/dev/null
이름으로 찾기: -name과 -iname
-name은 경로가 아닌 파일 이름만 패턴과 비교합니다. 패턴에서는 *(임의의 문자열), ?(임의의 문자 한 개), [abc](나열한 문자 중 하나)를 쓸 수 있습니다.
# 정확한 이름
find /etc -name 'hosts'
# 확장자가 .conf인 모든 파일
find /etc -name '*.conf'
# 대소문자 무시: README.md, readme.MD, Readme.md
find ~/projects -iname 'readme.md'
# report_1.csv ~ report_9.csv
find . -name 'report_?.csv'
패턴은 항상 따옴표로 감싸십시오. 따옴표가 없으면 셸이 현재 디렉터리의 파일을 먼저 확장해 버려서, find는 패턴이 아니라 파일 이름 목록을 받게 됩니다. 결과가 이상해지거나 paths must precede expression 오류가 납니다.
경로로 찾기: -path와 -regex
디렉터리까지 조건에 넣어야 한다면 -path를 쓰십시오. 이 옵션은 전체 경로를 패턴과 비교합니다.
# src 디렉터리 안에 있는 .js 파일만
find . -path '*/src/*' -name '*.js'
더 복잡한 패턴에는 -regex(역시 전체 경로 기준)를, 대소문자를 무시하려면 -iregex를 쓸 수 있습니다.
find . -regextype posix-extended -regex '.*\.(jpg|jpeg|png)$'
특정 디렉터리 제외하기
node_modules나 .git 안으로 들어가지 않으려면 -prune을 씁니다.
find . -path ./node_modules -prune -o -name '*.js' -print
이렇게 읽습니다. "경로가 ./node_modules라면 그 안으로 내려가지 말고, 그 밖의 경우(-o)에는 *.js 파일을 출력하라." 마지막의 -print는 꼭 있어야 합니다. 없으면 제외된 디렉터리 자체도 출력됩니다. 더 간단하지만 느린 방법은 -not -path '*/node_modules/*'입니다. 이 경우 find는 디렉터리 안을 여전히 모두 훑고, 결과만 걸러냅니다.
종류로 찾기: -type
| 값 | 찾는 대상 |
|---|---|
-type f | 일반 파일 |
-type d | 디렉터리 |
-type l | 심볼릭 링크 |
-type s | 소켓 |
-type p | 명명된 파이프(FIFO) |
# 이름이 logs인 디렉터리만
find / -type d -name 'logs' 2>/dev/null
# 빈 파일과 빈 디렉터리
find . -type f -empty
find . -type d -empty
# 깨진 심볼릭 링크
find . -xtype l
크기로 찾기: -size
-size는 숫자와 단위를 받습니다. c는 바이트, k는 킬로바이트, M은 메가바이트, G는 기가바이트입니다. 숫자 앞의 +는 "초과", -는 "미만", 부호가 없으면 "정확히"를 뜻합니다.
# 시스템 전체에서 100MB보다 큰 파일
find / -type f -size +100M 2>/dev/null
# 10MB 초과 50MB 미만
find . -type f -size +10M -size -50M
# 1KB 미만
find . -type f -size -1k
주의할 점이 있습니다. 크기는 단위로 올림하여 계산됩니다. 그래서 -size -1M은 사실상 빈 파일만 찾습니다. 비어 있지 않은 파일은 올림 후 최소 1MB로 계산되기 때문입니다. 정확한 경계가 필요하면 더 작은 단위를 쓰십시오: -size -1024k.
무엇이 디스크를 차지하는지 확인하기
find를 ls와 sort에 연결하면 가장 큰 파일을 볼 수 있습니다.
find /var -type f -size +50M -exec ls -lh {} + 2>/dev/null | sort -k5 -rh | head
-rw-r----- 1 syslog adm 1.2G Oct 14 09:12 /var/log/syslog.1
-rw-r--r-- 1 root root 412M Oct 10 03:00 /var/backups/db.sql.gz
-rw-r----- 1 root adm 96M Oct 14 09:15 /var/log/nginx/access.log
디렉터리 전체의 크기를 보려면 du -sh가 편합니다. find는 깊숙한 곳의 거대한 파일 하나가 용량을 잡아먹고 있을 때 특히 유용합니다.
날짜로 찾기: -mtime, -mmin, -newer
파일에는 시각 정보가 세 가지 있고, find는 각각으로 필터링할 수 있습니다.
| 조건 | 기준 시각 | 단위 |
|---|---|---|
-mtime / -mmin | 내용 수정 | 일 / 분 |
-atime / -amin | 마지막 읽기 | 일 / 분 |
-ctime / -cmin | 메타데이터 변경(권한, 소유자, 이름) | 일 / 분 |
부호 규칙은 크기와 같습니다. -mtime -7은 7일 이내에 수정된 파일, -mtime +30은 30일보다 전에 수정된 파일입니다.
# 최근 일주일 안에 수정된 파일
find ~/projects -type f -mtime -7
# 30일이 지난 로그
find /var/log -type f -name '*.log' -mtime +30
# 최근 15분 안에 수정된 설정 파일
find /etc -type f -mmin -15
일 단위는 24시간 단위로 나누고 소수점 이하는 버립니다. 그래서 -mtime +1은 24시간이 아니라 48시간보다 오래된 파일을 찾습니다. 이것은 자주 걸리는 함정입니다. 정확한 시간이 필요하면 분 단위를 쓰십시오: -mmin +1440.
다른 파일이나 특정 날짜보다 새로운 파일
# deploy.lock이 수정된 이후에 바뀐 파일
find . -type f -newer deploy.lock
# 특정 날짜 이후에 수정된 파일 (GNU find)
find . -type f -newermt '2026-10-01'
# 날짜 구간
find . -type f -newermt '2026-10-01' ! -newermt '2026-10-08'
소유자와 권한으로 찾기
# alice 사용자의 파일
find /home -user alice
# 소유자 계정이 없는 파일 (사용자를 삭제한 뒤 남은 파일)
find / -nouser 2>/dev/null
# 권한이 정확히 777인 파일
find /var/www -type f -perm 777
# 모든 사용자가 쓸 수 있는 파일
find /var/www -perm -o=w
# SUID 비트가 설정된 파일 (보안 점검에 유용)
find / -perm -4000 -type f 2>/dev/null
-perm에는 세 가지 형식이 있습니다. 숫자만 쓰면 권한이 정확히 일치해야 합니다. -를 붙이면 지정한 모든 비트가 설정되어 있어야 합니다. /를 붙이면 지정한 비트 중 하나라도 설정되어 있으면 됩니다.
조건의 논리: 그리고, 또는, 아님
조건은 기본적으로 "그리고"로 연결됩니다. "또는"에는 -o를, 부정에는 !나 -not을 씁니다. 묶음은 괄호로 지정하는데, 괄호는 셸에서 이스케이프해야 합니다.
# jpg 또는 png 이미지
find . -type f \( -name '*.jpg' -o -name '*.png' \)
# .tmp 파일을 제외한 모든 것
find . -type f ! -name '*.tmp'
괄호가 없으면 -type f는 "또는" 쌍의 첫 번째 조건에만 적용되고, *.png라는 이름의 디렉터리까지 결과에 들어갈 수 있습니다. \(와 \) 양옆의 공백은 필수입니다.
깊이 제한: -maxdepth와 -mindepth
# 현재 디렉터리만, 하위 디렉터리는 제외
find . -maxdepth 1 -type f -name '*.sh'
# 두 번째 수준 하위부터
find . -mindepth 2 -name '*.md'
# 다른 파일 시스템으로 넘어가지 않기
find / -xdev -type f -size +1G
-maxdepth는 경로 바로 뒤, 다른 조건 앞에 두십시오. 그렇지 않으면 GNU find가 경고를 출력합니다. -xdev는 /에서 검색할 때 유용합니다. 이 옵션이 있으면 find는 /proc, 네트워크 드라이브, 마운트된 다른 디스크로 들어가지 않습니다.
찾은 파일에 동작 적용하기: -exec, -delete, xargs
-exec: 각 파일에 명령 실행
find는 {} 자리에 파일 경로를 넣습니다. 명령은 \; 또는 +로 끝납니다.
# 파일마다 한 번씩 실행
find . -name '*.sh' -exec chmod +x {} \;
# 모든 파일을 한 번에 넘기기: 더 빠름
find . -name '*.log' -exec gzip {} +
# 파일마다 확인을 받으며 실행
find . -name '*.bak' -ok rm {} \;
+는 경로를 묶음으로 모아 명령을 훨씬 적게 실행하므로, 수천 개의 파일에서는 몇 배 빠릅니다. \;는 명령이 파일 하나만 받을 때, 또는 {}가 맨 끝에 오지 않을 때 필요합니다.
-delete: 찾은 파일 삭제
# 먼저 삭제 대상을 확인
find /tmp/build -type f -name '*.o' -mtime +7
# 그다음 삭제
find /tmp/build -type f -name '*.o' -mtime +7 -delete
항상 -delete 없이 먼저 실행해 목록을 확인하십시오. 그리고 -delete는 반드시 맨 뒤에 두십시오. find는 조건을 왼쪽에서 오른쪽으로 평가하므로, find . -delete -name '*.o'는 디렉터리 안의 모든 것을 지운 뒤에야 이름을 검사합니다.
find와 xargs
고전적인 조합은 xargs로 파일 목록을 다른 프로그램에 넘기는 것입니다. 공백이 들어간 이름에서도 깨지지 않으려면 널 문자 구분자를 쓰십시오.
find . -type f -name '*.txt' -print0 | xargs -0 wc -l
xargs의 -P 옵션은 병렬로 실행합니다.
find ./images -name '*.png' -print0 | xargs -0 -P 4 -n 10 optipng
find와 grep: 파일 안의 텍스트 찾기
find는 파일을 찾을 뿐 내용을 검색하지는 않습니다. 선택한 파일 안에서 문자열을 찾으려면 결과를 grep에 넘기십시오.
# 설정 파일 중 listen 8080이 있는 곳
find /etc/nginx -type f -name '*.conf' -exec grep -Hn 'listen 8080' {} +
/etc/nginx/sites-enabled/app.conf:4: listen 8080;
-H는 파일 이름을, -n은 줄 번호를 출력합니다. grep -l은 일치하는 파일 이름만 보여 줍니다. 확장자로만 거르면 grep 자체로 충분합니다: grep -rn --include='*.conf' 'listen 8080' /etc/nginx.
출력 형식 바꾸기: -printf
GNU find는 경로만이 아니라 원하는 정보를 골라 출력할 수 있습니다. 예를 들어 크기, 날짜, 이름을 함께 출력하려면 다음과 같이 합니다.
find . -maxdepth 1 -type f -printf '%s\t%TY-%Tm-%Td\t%p\n' | sort -n
%s는 바이트 단위 크기, %T...는 수정 날짜의 각 부분, %p는 경로입니다. 스크립트에서 ls의 출력을 파싱할 필요가 없어서 편리합니다.
매일 쓰는 find 리눅스 예제 모음
| 과제 | 명령 |
|---|---|
| 이름으로 파일 찾기 | find / -name 'file.txt' 2>/dev/null |
| 대소문자 무시 | find . -iname '*.jpg' |
| 디렉터리만 | find . -type d -name 'cache' |
| 1GB보다 큰 파일 | find / -xdev -type f -size +1G |
| 하루 안에 수정된 파일 | find . -type f -mtime -1 |
| 한 시간 안에 수정된 파일 | find . -type f -mmin -60 |
| 30일 지난 로그 삭제 | find /var/log/app -name '*.log' -mtime +30 -delete |
| 빈 디렉터리 | find . -type d -empty |
| 모든 디렉터리 권한 변경 | find . -type d -exec chmod 755 {} + |
| 파일 안의 문자열 찾기 | find . -name '*.py' -exec grep -l 'TODO' {} + |
| 파일 개수 세기 | find . -type f | wc -l |
흔한 실수
- 패턴에 따옴표가 없음.
find . -name *.log는 현재 디렉터리에.log파일이 하나라도 있으면 깨집니다.'*.log'처럼 따옴표를 쓰십시오. - Permission denied 쏟아짐.
2>/dev/null을 붙이거나, 디스크 전체 검색이 정말 필요하다면sudo로 실행하십시오. -delete의 위치 잘못. 항상 맨 뒤에 두고, 그 전에 삭제 없이 한 번 실행해 확인하십시오.- 파이프에서 공백이 든 이름.
find ... | xargs rm은 "My File.txt"를 두 인자로 쪼갭니다.-print0과xargs -0, 또는-exec를 쓰십시오. -mtime이 정확한 날짜를 뜻한다고 생각함. 정확한 간격이 필요하면-mmin이나-newermt를 쓰십시오.
정리
find는 파일 시스템을 검색하는 범용 도구입니다. 경로를 정하고, 이름, 종류, 크기, 날짜, 권한으로 조건을 만든 뒤, 동작을 지정하면 됩니다. -name, -type, -size, -mtime, -exec ... + 다섯 가지만 익혀도 대부분의 과제를 한 줄로 해결할 수 있습니다. 이 find 리눅스 예제들은 직접 터미널에서 따라 해 보시기 바랍니다. find와 grep, sed, awk를 함께 쓰는 방법은 강의의 텍스트 처리 실습에서 다룹니다.
자주 묻는 질문
find와 locate는 무엇이 다른가요?
locate는 미리 만들어 둔 이름 데이터베이스를 검색하므로 즉시 결과를 주지만, updatedb 이후에 만들어진 파일은 찾지 못합니다. find는 디스크를 실시간으로 훑으며 크기, 날짜, 권한으로도 거를 수 있습니다.
파일 이름이 아니라 내용으로 찾으려면 어떻게 하나요?
find 자체는 내용을 읽지 않습니다. grep -rn '문자열' /경로를 쓰거나, find . -name '*.conf' -exec grep -l '문자열' {} +를 쓰십시오.
루트 디렉터리에서 find가 너무 느린 이유는 무엇인가요?
/proc, /sys, 마운트된 모든 디스크까지 훑기 때문입니다. 검색 범위를 특정 디렉터리로 좁히고, -xdev와 -maxdepth를 쓰거나 -prune으로 불필요한 곳을 제외하십시오.
find 결과를 수정 날짜순으로 정렬할 수 있나요?
네. find . -type f -printf '%T@ %p\n' | sort -n은 오래된 파일부터 보여 줍니다. %T@는 수정 시각을 1970년 이후 경과 초로 출력합니다.
빈 디렉터리를 찾아서 삭제하려면 어떻게 하나요?
find . -type d -empty -delete로 빈 디렉터리를 지울 수 있습니다. 하위 파일을 지우면서 비게 된 디렉터리도 함께 지워집니다. 먼저 -delete 없이 실행해 목록을 확인하십시오.