개발자 터미널 도구 모음 — jq, httpie, fzf, ripgrep

왜 CLI 도구를 익혀야 하는가?

GUI 도구는 직관적이지만, CLI 도구는 자동화, 파이프라인 조합, 속도 면에서 압도적입니다. 요리에 비유하면, GUI는 전자레인지(편리하지만 제한적)이고 CLI는 칼과 도마(숙련되면 모든 요리가 가능)입니다.

이 글에서는 일상 개발에서 즉시 생산성을 높여주는 4가지 CLI 도구를 정리합니다.

jq: JSON 처리의 스위스 칼

jq는 커맨드라인에서 JSON을 파싱, 필터링, 변환하는 도구입니다. API 응답을 분석하거나, JSON 로그를 처리할 때 필수입니다.

설치

# macOS
brew install jq

# Ubuntu/Debian
sudo apt install jq

# Windows (scoop)
scoop install jq

기본 사용법

# JSON 이쁘게 출력 (Pretty Print)
echo '{"name":"김철수","age":30}' | jq '.'
# 출력:
# {
#   "name": "김철수",
#   "age": 30
# }

# 특정 필드 추출
echo '{"name":"김철수","age":30,"city":"서울"}' | jq '.name'
# 출력: "김철수"

# 따옴표 없이 출력 (-r 옵션)
echo '{"name":"김철수"}' | jq -r '.name'
# 출력: 김철수

# 배열에서 필터링
echo '[{"name":"김철수","age":30},{"name":"이영희","age":25}]' | jq '.[] | select(.age > 27)'
# 출력: {"name":"김철수","age":30}

# 새로운 구조로 변환
echo '[{"first":"철수","last":"김"},{"first":"영희","last":"이"}]' | \
  jq '[.[] | {full_name: (.last + .first), initial: .last}]'
# 출력:
# [
#   { "full_name": "김철수", "initial": "김" },
#   { "full_name": "이영희", "initial": "이" }
# ]

실전 예제: API 응답 분석

# GitHub API에서 리포지토리 정보 추출
curl -s "https://api.github.com/users/torvalds/repos?per_page=5" | \
  jq '[.[] | {name: .name, stars: .stargazers_count, language: .language}]' | \
  jq 'sort_by(-.stars)'
# 출력:
# [
#   { "name": "linux", "stars": 180000, "language": "C" },
#   ...
# ]

# JSON 로그에서 에러만 추출
cat app.log | jq -r 'select(.level == "error") | "\(.timestamp) \(.message)"'
# 출력: 2026-04-07T10:00:01 Database connection failed

# 중첩 JSON에서 깊은 필드 접근
echo '{"data":{"users":[{"id":1,"profile":{"email":"a@b.com"}}]}}' | \
  jq '.data.users[0].profile.email'
# 출력: "a@b.com"

HTTPie: curl의 현대적 대안

HTTPie는 사람이 읽기 쉬운 HTTP 클라이언트입니다. curl보다 직관적인 문법으로 API를 테스트할 수 있습니다.

설치

# macOS
brew install httpie

# pip (모든 플랫폼)
pip install httpie

# Ubuntu
sudo apt install httpie

기본 사용법

# GET 요청 (프로토콜, 메서드 생략 가능)
http httpbin.org/get
# 출력: (자동 색상 + 포매팅된 JSON 응답)

# POST 요청 + JSON 본문 (= 구분자로 키-값 전달)
http POST httpbin.org/post name=김철수 age:=30 active:=true
# name=값 → 문자열
# age:=30 → 숫자 (: 붙이면 JSON 타입)
# active:=true → 불린

# 헤더 추가 (: 구분자)
http GET api.example.com/users \
  Authorization:"Bearer eyJhbGci..." \
  Accept:application/json

# 파일 업로드
http --form POST api.example.com/upload file@./document.pdf

# 폼 데이터 전송
http --form POST api.example.com/login username=admin password=1234

curl과 비교

# curl로 POST 요청
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer token123" \
  -d '{"name":"김철수","age":30}'

# HTTPie로 동일한 요청 (훨씬 간결)
http POST api.example.com/users \
  name=김철수 age:=30 \
  Authorization:"Bearer token123"
기능curlHTTPie
JSON 포매팅수동 (`jq`)
색상 출력없음자동
JSON 본문-d '{"key":"val"}'key=val
헤더 추가-H "Key: Val"Key:Val
파일 업로드-F "file=@path"file@path

세션 기능

# 세션 저장 — 쿠키/헤더 유지
http --session=myapi POST api.example.com/login username=admin password=1234
# 로그인 쿠키가 세션에 저장됨

# 이후 요청에서 세션 재사용 (인증 정보 자동 포함)
http --session=myapi GET api.example.com/profile
# 쿠키가 자동으로 전송됨

fzf: 퍼지 파인더

fzf는 모든 목록을 실시간 퍼지 검색할 수 있는 도구입니다. 파일, 히스토리, 브랜치 등 무엇이든 빠르게 찾을 수 있습니다.

설치

# macOS
brew install fzf
$(brew --prefix)/opt/fzf/install  # 키 바인딩 설정

# Ubuntu
sudo apt install fzf

# Git에서 직접 설치
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

기본 사용법

# 현재 디렉토리에서 파일 검색
fzf
# 입력: "comp"
# 매칭: src/components/Button.tsx, docker-compose.yml, ...
# ↑↓로 선택, Enter로 확정

# 파이프와 조합
cat package.json | jq -r '.dependencies | keys[]' | fzf
# npm 패키지 목록에서 퍼지 검색

# 미리보기 포함 파일 검색
fzf --preview 'cat {}'
# 선택한 파일의 내용을 오른쪽에 미리보기

# 여러 항목 선택 (Tab으로 선택, Enter로 확정)
fzf --multi

셸 통합 (핵심 기능)

# fzf 설치 시 자동 설정되는 키 바인딩

# Ctrl+R — 명령어 히스토리 퍼지 검색 (가장 많이 사용!)
# 평소: history | grep docker → 느림
# fzf:  Ctrl+R → "docker" 입력 → 즉시 찾기

# Ctrl+T — 현재 디렉토리에서 파일/디렉토리 퍼지 검색
# vim Ctrl+T → 파일 선택 → vim으로 열기

# Alt+C — 디렉토리 퍼지 검색 후 cd
# Alt+C → "comp" → src/components/ 로 이동

Git과 조합

# Git 브랜치 퍼지 검색 후 체크아웃
git branch -a | fzf | xargs git checkout

# Git 로그에서 커밋 검색
git log --oneline | fzf --preview 'git show {1}'
# 커밋 해시 기준으로 diff 미리보기

# 변경된 파일 중 선택하여 add
git status -s | fzf --multi | awk '{print $2}' | xargs git add

# 셸 함수로 등록 (~/.bashrc 또는 ~/.zshrc)
# Git 브랜치 퍼지 체크아웃
gbf() {
  local branch
  branch=$(git branch -a | sed 's/^..//' | sed 's|remotes/origin/||' | sort -u | fzf)
  if [ -n "$branch" ]; then
    git checkout "$branch"
  fi
}

ripgrep (rg): grep의 초고속 대안

ripgrep은 코드 검색에 최적화된 grep 대안입니다. .gitignore를 자동 인식하고, 기본적으로 재귀 검색하며, grep보다 2~5배 빠릅니다.

설치

# macOS
brew install ripgrep

# Ubuntu
sudo apt install ripgrep

# Windows (scoop)
scoop install ripgrep

# cargo (Rust)
cargo install ripgrep

기본 사용법

# 현재 디렉토리에서 재귀 검색 (기본 동작)
rg "TODO"
# 출력:
# src/app.ts:42:  // TODO: 에러 핸들링 추가
# src/utils.ts:15: // TODO: 캐시 구현

# 대소문자 무시
rg -i "error"

# 파일 타입 필터
rg "import" --type ts          # TypeScript 파일만
rg "def " --type py            # Python 파일만
rg "SELECT" --type sql         # SQL 파일만

# 특정 디렉토리에서 검색
rg "useState" src/components/

# 정규표현식 검색
rg "console\.(log|warn|error)" --type ts
# console.log, console.warn, console.error 모두 찾기

# 매칭되는 파일명만 출력
rg -l "TODO"
# 출력:
# src/app.ts
# src/utils.ts

고급 사용법

# 컨텍스트 라인 표시 (위아래 2줄)
rg "error" -C 2

# 특정 패턴 제외
rg "import" --type ts --glob '!**/*.test.ts'  # 테스트 파일 제외

# JSON 출력 (다른 도구와 조합용)
rg "TODO" --json | jq 'select(.type == "match") | .data.lines.text'

# 파일별 매칭 수 카운트
rg -c "console.log" --type ts | sort -t: -k2 -rn
# 출력: (console.log가 많은 파일 순으로 정렬)
# src/debug.ts:15
# src/app.ts:8
# src/utils.ts:3

# 치환 (파일 수정 없이 결과만 미리보기)
rg "old_function" --replace "new_function"

# grep과의 속도 비교 (대규모 프로젝트에서)
# grep -r "pattern" .    → 약 3초
# rg "pattern"           → 약 0.3초 (10배 빠름)

fzf + ripgrep 조합

# ripgrep으로 검색 + fzf로 선택 + 에디터로 열기
rg --line-number "TODO" | fzf --delimiter : --preview 'cat -n {1} | head -{2}' | \
  awk -F: '{print "+" $2, $1}' | xargs code -g
# TODO가 있는 줄을 퍼지 검색하고, 선택하면 VS Code에서 해당 줄로 이동

# 인터랙티브 ripgrep (fzf에서 실시간 검색)
rg_fzf() {
  rg --line-number --color=always "$1" | \
    fzf --ansi --delimiter : \
        --preview 'cat -n {1}' \
        --preview-window 'right:60%'
}
# 사용: rg_fzf "pattern"

도구 조합 치트시트

# API 응답에서 특정 필드 추출 후 퍼지 선택
http GET api.example.com/users | jq -r '.[].name' | fzf

# 로그 파일에서 에러 패턴 검색 후 컨텍스트 확인
rg "ERROR" logs/ -C 3 | fzf --ansi

# 프로세스 검색 후 종료
ps aux | fzf | awk '{print $2}' | xargs kill

# JSON 파일 찾기 + 내용 검색
rg -t json "api_key" | fzf

설치 요약

도구macOSUbuntuWindows용도
jqbrew install jqapt install jqscoop install jqJSON 처리
HTTPiebrew install httpieapt install httpiepip install httpieHTTP 클라이언트
fzfbrew install fzfapt install fzfscoop install fzf퍼지 검색
ripgrepbrew install ripgrepapt install ripgrepscoop install ripgrep코드 검색

실전 팁

  • Ctrl+R (fzf 히스토리 검색)부터 익히세요: 이것 하나만으로도 터미널 생산성이 크게 향상됩니다. 긴 명령어를 다시 타이핑할 필요가 없습니다.
  • jq는 API 테스트에 필수입니다: curl ... | jq '.data'처럼 API 응답을 즉시 파싱하여 원하는 필드만 확인할 수 있습니다.
  • rggrep -r 대신 사용하세요: .gitignore를 자동 인식하므로 node_modulesdist 폴더를 건너뛰고, 속도도 훨씬 빠릅니다.
  • 도구를 조합하세요: 파이프(|)로 도구를 연결하면 각 도구의 강점을 결합할 수 있습니다. rg | fzf, curl | jq | fzf 같은 조합이 매우 강력합니다.
  • 셸 함수/별칭을 만드세요: 자주 쓰는 조합을 ~/.bashrc~/.zshrc에 함수로 등록하면, 한 단어로 복잡한 작업을 수행할 수 있습니다.
  • bat을 함께 설치하세요: cat 대신 bat을 사용하면 구문 강조된 파일 내용을 볼 수 있어, fzf의 미리보기가 더 유용해집니다.

이 글이 도움이 되었나요?