Skip to content

fd - Street-Level Ops

Real-world workflows for finding files fast in DevOps environments.

Finding Config Files Across a Project

# Find all YAML config files
fd -e yaml -e yml

# Find Dockerfiles anywhere in the tree
fd -g 'Dockerfile*'

# Output:
# services/api/Dockerfile
# services/worker/Dockerfile
# services/api/Dockerfile.test

# Find Terraform files
fd -e tf -e tfvars

# Find all Helm chart files
fd -g 'Chart.yaml'

# Output:
# devops/helm/grokdevops/Chart.yaml
# devops/helm/monitoring/Chart.yaml

Finding Files by Size and Age

# Find large log files consuming disk space
fd -e log -t f --size +100m

# Output:
# /var/log/app/access.log
# /var/log/app/error.log
# /var/log/elasticsearch/gc.log

# Find files modified in the last hour (recent changes)
fd -t f --changed-within 1h

# Find temp files older than 30 days (cleanup candidates)
fd -e tmp -e bak -e swp --changed-before 30d

# Find empty directories (cleanup candidates)
fd -t e -t d

Batch Operations on Found Files

# Syntax-check all shell scripts
fd -e sh --exec-batch bash -n

# Lint all Python files with ruff
fd -e py --exec-batch ruff check

# Compile-check all Python files
fd -e py --exec python3 -m py_compile {}

# Output (per file, parallel):
# (no output = success)

# Find and delete all .pyc files
fd -e pyc --exec rm {}

# Find and chmod all scripts to executable
fd -e sh --exec chmod +x {}

Excluding Noise

# Search but skip common noise directories
fd -E node_modules -E .git -E __pycache__ -E .terraform "config"

# Search only git-tracked files (respects .gitignore by default)
fd "test"

# Include hidden files (dotfiles) that are normally skipped
fd --hidden "bashrc"

# Include gitignored files (e.g., searching in build output)
fd --no-ignore "bundle"

# Limit depth to avoid deep traversal
fd -d 2 "README"

# Output:
# README.md
# training/README.md
# devops/README.md

DevOps-Specific Patterns

# Find all Kubernetes manifests
fd -e yaml -g '*deployment*' devops/k8s/

# Find all test files
fd -g '*test*' -e py -e sh

# Find all values files for Helm
fd -g 'values*.yaml'

# Output:
# devops/helm/values-dev.yaml
# devops/helm/values-staging.yaml
# devops/helm/values-prod.yaml

# Find all Ansible playbooks
fd -g '*.yml' devops/ansible/playbooks/

# Find all CI/CD config files
fd -g '*.yml' .github/workflows/ .gitlab-ci* Jenkinsfile

Combining fd with Other Tools

# fd + fzf: interactive file picker with preview
fd -t f | fzf --preview 'head -30 {}'

# fd + rg: find files then search contents
fd -e yaml | xargs rg "replicas"

# fd + xargs with null separator (safe for filenames with spaces)
fd -0 -e py | xargs -0 ruff check

# fd + wc: count lines in all Python files
fd -e py --exec-batch wc -l | tail -1

# fd + tar: archive all config files
fd -e conf -e yaml -0 | xargs -0 tar czf configs-backup.tar.gz

Comparing fd and find Side by Side

# Task: find YAML files modified in the last day, excluding .terraform

# find (verbose, easy to get wrong)
find . -name '*.yaml' -not -path '*/.terraform/*' -mtime -1 -type f

# fd (concise, .gitignore-aware by default)
fd -e yaml -E .terraform --changed-within 1d

# Task: find and delete all .bak files older than 7 days

# find
find /var/log -name '*.bak' -mtime +7 -type f -exec rm {} \;

# fd
fd -e bak --changed-before 7d /var/log --exec rm {}

Configuration for DevOps Work

# ~/.fdignore (global ignore patterns)
cat > ~/.fdignore << 'EOF'
node_modules/
.terraform/
__pycache__/
.git/
*.pyc
.ruff_cache/
.pytest_cache/
EOF

# Project-level .fdignore
cat > .fdignore << 'EOF'
_attic/
build/
dist/
*.egg-info/
EOF

# fd also reads .ignore files (shared with ripgrep)