fd로 파일 찾기: find보다 빠르고 편한 검색 도구
프로젝트 디렉토리에서 특정 파일을 찾으려고 find . -name '*.ts'를 입력했는데 node_modules 안의 파일까지 끝도 없이 쏟아져 나온 경험, 한 번쯤 있지 않으신가요? 아니면 find 명령어의 옵션이 너무 많아서 매번 검색해보게 되는 분도 계실 거예요.
이럴 때 써볼 만한 도구가 바로 fd입니다. fd는 기존 find 명령어를 대체하기 위해 만들어진 커맨드라인 도구인데요. 직관적인 문법, .gitignore 자동 적용, 병렬 탐색을 통한 빠른 속도가 특징입니다. Rust로 작성되어 있고 ripgrep에서 사용하는 regex와 ignore 크레이트(crate)를 활용해서 find보다 훨씬 빠릅니다.
이번 글에서는 fd의 설치부터 핵심 옵션과 실전 활용법까지 살펴보겠습니다.
설치
macOS에서는 Homebrew로 설치하면 됩니다.
brew install fd
Linux(Debian/Ubuntu)에서는 패키지 이름이 fd-find입니다.
sudo apt install fd-find
Ubuntu/Debian에서는 바이너리 이름이
fdfind로 설치됩니다.fd로 쓰고 싶다면ln -s $(which fdfind) ~/.local/bin/fd처럼 심볼릭 링크를 만들어주세요.
Windows에서는 Scoop이나 Chocolatey를 쓸 수 있습니다.
scoop install fd
설치가 끝나면 버전을 확인해볼까요?
fd --version
fd 10.2.0
find와 비교
fd가 왜 편한지 find와 비교하면 바로 느낌이 옵니다. 현재 디렉토리에서 이름에 test가 들어간 파일을 찾는다고 해볼게요.
# find 사용
find . -iname '*test*'
# fd 사용
fd test
find는 -iname 옵션에 와일드카드(*)까지 직접 감싸줘야 하는데, fd는 패턴만 넘기면 알아서 부분 매칭을 해줍니다. 대소문자도 기본적으로 구분하지 않고요 (스마트 케이스).
.gitignore에 등록된 파일은 자동으로 제외하고, 숨김 파일도 기본적으로 감춰줍니다. node_modules나 .git 같은 디렉토리가 결과에 포함되지 않으니 원하는 파일을 훨씬 빠르게 찾을 수 있죠.
기본 사용법
가장 기본적인 사용법은 검색 패턴을 인자로 넘기는 겁니다.
fd README
README.md
docs/README.md
패턴 없이 fd만 실행하면 현재 디렉토리의 모든 파일과 디렉토리를 재귀적으로 보여줍니다. 숨김 파일과 .gitignore 대상은 제외되니까 ls -R보다 훨씬 깔끔합니다.
fd
특정 디렉토리에서 검색하려면 두 번째 인자로 경로를 넘기면 됩니다.
fd config /etc
/etc/ssh/ssh_config
/etc/ssh/sshd_config
/etc/pam.d/common-password
정규표현식 검색
fd는 기본적으로 정규표현식을 사용합니다. 단순 문자열도 정규표현식의 일부이니 자연스럽게 동작하고요.
# test로 시작하는 파일
fd '^test'
# .ts 또는 .tsx로 끝나는 파일
fd '\.tsx?$'
# 숫자가 포함된 파일명
fd '[0-9]'
정규표현식 대신 glob 패턴을 쓰고 싶다면 -g 옵션을 주면 됩니다.
fd -g '*.md'
확장자로 필터링
파일 확장자로 검색할 때는 -e 옵션이 가장 간편합니다.
# 모든 TypeScript 파일
fd -e ts
# 모든 마크다운 파일 중 이름에 react가 포함된 것
fd -e md react
여러 확장자를 동시에 검색할 수도 있어요.
fd -e jpg -e png -e svg
파일 타입 필터링
-t 옵션으로 파일, 디렉토리, 심볼릭 링크 등 타입별로 필터링할 수 있습니다.
# 디렉토리만 검색
fd -t d src
# 파일만 검색
fd -t f config
# 실행 파일만 검색
fd -t x
지원하는 타입은 f(파일), d(디렉토리), l(심볼릭 링크), x(실행 파일), e(빈 파일/디렉토리), s(소켓), p(파이프)입니다.
숨김 파일과 무시 파일
fd는 기본적으로 숨김 파일을 제외하고 .gitignore 규칙을 따릅니다. 이 동작을 바꾸려면 다음 옵션을 사용합니다.
# 숨김 파일 포함
fd -H pre-commit
# .gitignore 무시 (무시된 파일도 검색)
fd -I node_modules
# 둘 다 적용 (모든 파일 검색)
fd -HI
-u(unrestricted) 옵션을 쓸 수도 있는데, -u는 -H와 같고 -uu는 -HI와 같습니다.
# 숨김 파일 포함
fd -u .bashrc
# 모든 파일 검색 (숨김 + 무시 파일)
fd -uu node_modules
검색 깊이 제한
-d 옵션으로 디렉토리 탐색 깊이를 제한할 수 있습니다.
# 현재 디렉토리에서만 검색 (하위 디렉토리 탐색 안 함)
fd -d 1
# 최대 2단계까지만 검색
fd -d 2 config
특정 경로 제외
-E 옵션으로 특정 패턴을 검색 결과에서 제외할 수 있습니다.
# node_modules 제외
fd -E node_modules '\.js$'
# 여러 패턴 제외
fd -E '*.min.js' -E dist -e js
자주 제외하는 패턴이 있다면 프로젝트 루트에 .fdignore 파일을 만들어서 관리할 수 있습니다. 문법은 .gitignore와 동일합니다.
node_modules
dist
build
*.min.js
크기와 시간으로 필터링
파일 크기로 필터링하려면 -S 옵션을 씁니다.
# 1MB보다 큰 파일
fd -S +1m
# 100KB 이하인 파일
fd -S -100k
# 이미지 중 5MB 이상인 것
fd -e jpg -e png -S +5m
수정 시간 기준으로도 필터링할 수 있어요.
# 최근 1시간 내에 수정된 파일
fd --changed-within 1h
# 최근 7일 내에 수정된 마크다운 파일
fd -e md --changed-within 7d
# 30일 이전에 수정된 로그 파일
fd -e log --changed-before 30d
검색 결과로 명령어 실행
fd의 강력한 기능 중 하나가 검색 결과를 기반으로 명령어를 실행하는 거예요. -x 옵션은 각 결과에 대해 명령어를 병렬로 실행하고, -X 옵션은 모든 결과를 한 번에 넘깁니다.
# 모든 .tmp 파일 삭제
fd -e tmp -x rm
# 모든 .jpg 파일을 .png로 변환
fd -e jpg -x convert {} {.}.png
# 모든 테스트 파일을 에디터로 열기
fd -g 'test_*.py' -X vim
-x에서 사용할 수 있는 플레이스홀더(placeholder)는 다음과 같습니다.
| 플레이스홀더 | 설명 | 예시 (src/utils/helper.ts) |
|---|---|---|
{} | 전체 경로 | src/utils/helper.ts |
{.} | 확장자 제외 | src/utils/helper |
{/} | 파일명만 | helper.ts |
{//} | 디렉토리만 | src/utils |
{/.} | 파일명(확장자 제외) | helper |
예를 들어, 모든 마크다운 파일의 줄 수를 세려면 이렇게 할 수 있습니다.
fd -e md -x wc -l
출력 옵션
fd는 기본적으로 상대 경로를 출력하는데, 상황에 따라 출력 형식을 바꿀 수 있습니다.
절대 경로가 필요하면 -a 옵션을 씁니다. 스크립트에서 경로를 다른 도구에 넘길 때 유용해요.
fd -a -e ts
/home/user/project/src/index.ts
/home/user/project/src/utils/helper.ts
ls -l처럼 파일의 권한, 크기, 수정 시간까지 보고 싶다면 -l 옵션을 주면 됩니다.
fd -e sh -l
.rwxr-xr-x 245 user 3 Mar 12:30 scripts/build.sh
.rwxr-xr-x 189 user 1 Mar 09:15 scripts/deploy.sh
파일명이 아니라 전체 경로를 기준으로 패턴을 매칭하고 싶을 때는 -p 옵션을 사용합니다.
# src/utils 디렉토리 안의 .ts 파일만 검색
fd -p 'src/utils/.*\.ts$'
fzf와 함께 사용
fd는 퍼지 파인더(fuzzy finder)인 fzf와 궁합이 잘 맞습니다. 환경 변수를 설정해서 fzf의 기본 검색 명령어를 fd로 바꿀 수 있어요.
export FZF_DEFAULT_COMMAND='fd --type f'
이렇게 설정하면 fzf를 실행했을 때 fd가 파일 목록을 제공하니까 .gitignore에 등록된 파일이 자동으로 제외되고 검색 속도도 빨라집니다.
파이프로 직접 연결하는 방법도 있습니다.
# fd로 찾은 파일 중 하나를 선택해서 에디터로 열기
fd -e ts | fzf | xargs vim
실전 활용 예제
그동안 다룬 옵션을 조합하면 꽤 다양한 작업을 할 수 있는데, 제가 자주 쓰는 패턴 위주로 정리해봤습니다.
# 프로젝트에서 설정 파일 찾기
fd -g '*.config.*'
# 빈 디렉토리 정리
fd -t e -t d -x rmdir
# 최근 수정된 소스 파일 확인
fd -e ts -e tsx --changed-within 1d
# 특정 패턴의 파일 개수 세기
fd -e test.ts | wc -l
# 모든 package.json 파일 위치 확인 (모노레포)
fd -g package.json
# 큰 이미지 파일 찾기
fd -e jpg -e png -e gif -S +1m -l
# 오래된 로그 파일 정리
fd -e log --changed-before 30d -x rm
알아둘 점
fd는 POSIX 표준 도구가 아니라서 원격 서버에 SSH로 접속했을 때 설치되어 있지 않을 수 있습니다. 그런 환경에서는 find를 써야 하니 기본적인 find 문법도 함께 알아두는 게 좋습니다. 마찬가지로 fd의 형제 도구인 ripgrep도 설치가 필요하니, 기본 내장된 grep 명령어도 함께 익혀두면 좋습니다.
또한 Ubuntu/Debian에서는 앞서 언급했듯이 바이너리 이름이 fdfind이니 처음 설치 후 심볼릭 링크 설정을 잊지 마세요.
마치며
find를 쓸 때마다 옵션을 검색하곤 했는데, fd로 바꾸고 나서는 대부분 기억에 의존해서 쓰게 됐습니다. 문법 자체가 직관적이라 외울 게 별로 없거든요. fd test처럼 패턴만 넘기면 되니까요.
개인적으로 가장 마음에 드는 건 .gitignore 자동 적용입니다. find로 검색하면 node_modules가 쏟아지는 게 당연했는데, fd에서는 그런 걱정을 안 해도 됩니다. -x 옵션으로 검색 결과에 바로 명령어를 실행하는 것도 파일 정리할 때 요긴하고요.
더 자세한 옵션과 사용법은 fd GitHub 저장소에서 확인하실 수 있습니다.
This work is licensed under
CC BY 4.0