Skip to main content

fx-bin

PyPI version Python Tests Coverage Security Code style: black

A powerful, secure, and well-tested collection of Python file operation utilities with a unified CLI.

📋 Table of Contents

🤔 Why fx-bin?

fx-bin addresses common pain points in file operations:

  • Unified Interface: One command (fx) for all file operations - no need to remember multiple tools
  • Safety First: Built-in safeguards prevent accidental data loss (especially in fx replace)
  • Performance: Optimized algorithms handle large directories and files efficiently
  • Cross-Platform: Works seamlessly on Windows, macOS, and Linux
  • Developer Friendly: Comprehensive testing (95%+ coverage) and clean, maintainable code
  • Security Focused: Regular security audits, safe path handling, and input validation
  • Modern Python: Built with Python 3.11+ features and best practices

Whether you're organizing files, analyzing disk usage, performing bulk text replacements, or filtering files by type, fx-bin provides a reliable, fast, and safe solution.

✨ Features

Core Capabilities

  • 📁 File Counting - Quickly count files in directories with pattern matching

  • 📊 Size Analysis - Analyze file and directory sizes with human-readable output

  • 🔍 File Finding - Search for files by keywords with multiple search strategies

  • 🎯 File Filtering - Filter files by extension with intelligent sorting (NEW in v1.2.0!)

  • 🔄 Text Replacement - Safe, bulk text replacement across files with backup options

  • 💾 File Backup - Create timestamped backups of files and directories (NEW in v1.4.0!)

  • 📋 Command Listing - Built-in help and command discovery

Technical Excellence

  • 🛡️ Security Hardened - Protection against path traversal, command injection, and other vulnerabilities
  • Thoroughly Tested - TDD/BDD methodology with 95%+ test coverage
  • 🚀 High Performance - Optimized for large-scale operations
  • 🔧 Extensible - Clean architecture for easy feature additions
  • 📝 Well Documented - Comprehensive documentation and examples

🚀 Quick Start

# Install fx-bin
pip install fx-bin  # or: pipx install fx-bin

# Show help and available commands
fx help              # Same as fx -h
fx list              # Show all available commands

# Count Python files
fx files . --pattern "*.py"

# Find large files
fx size . --limit 10 --unit MB

# Filter documents by extension
fx filter ~/Documents "pdf,docx" --format detailed

# Find files containing keyword
fx ff TODO

# Safe text replacement
fx replace "old_text" "new_text" file.txt

📦 Installation

Via pip (Recommended)

pip install fx-bin

Via pipx (For Isolated Installation)

pipx install fx-bin

# Upgrade to latest version
pipx upgrade fx-bin

From Source

git clone https://github.com/frankyxhl/fx_bin.git
cd fx_bin
poetry install
poetry run fx --help

Requirements

  • Python 3.11 or higher
  • No external dependencies required for core functionality

🛠️ Commands

Overview

Command Description Key Features
fx files Count files in directories Pattern matching, recursive search, detailed stats
fx size Analyze file/directory sizes Human-readable units, sorting, limit results
fx ff Find files by keyword Path-segment matching (dir/file), clipboard copy by default, smart exclusions
fx fff Find first file matching keyword Alias for fx ff --first, fast single lookup
fx open (fx o) Open saved URLs/files and direct targets Local TOML registry, tags, browser/app selection
fx filter Filter files by extension Time-based sorting, multiple formats, recursive search
fx replace Replace text in files Atomic file operations, safe text replacement
fx backup Create timestamped backups File/dir backup, compression
fx root Find Git project root directory cd "$(fx root --cd)", script integration
fx repo Open the current GitHub repository origin preference, explicit remote selection
fx realpath (fx rp) Get absolute path of a file/directory Resolves ~, symlinks, relative paths
fx today Create/navigate to today's workspace Date-based daily directories
fx organize Organize files into date-based directories Photo sorting, dataset management
fx list List all available commands Help and usage information
fx version Show version and system information Diagnostics

Detailed Command Documentation

📁 fx files - File Counter

Count files in directories with powerful filtering options.

# Basic usage
fx files /path/to/directory

# Count only Python files
fx files . --pattern "*.py"

# Exclude test files
fx files . --exclude "*test*"

# Recursive search with details
fx files . --recursive --detailed

Options:

  • --pattern: File pattern to match (glob syntax)
  • --exclude: Pattern to exclude files
  • --recursive: Search subdirectories
  • --detailed: Show detailed statistics

📊 fx size - Size Analyzer

Analyze file and directory sizes with flexible output options.

# Show top 10 largest files
fx size . --limit 10

# Display sizes in MB
fx size . --unit MB

# Sort by size ascending
fx size . --sort asc

# Include hidden files
fx size . --all

Options:

  • --limit: Number of results to show
  • --unit: Size unit (B, KB, MB, GB)
  • --sort: Sort order (asc/desc)
  • --all: Include hidden files

🎯 fx filter - File Filter (NEW in v1.2.0!)

Filter files by extension with intelligent sorting capabilities.

# Find Python files sorted by creation time
fx filter . py

# Multiple extensions
fx filter . "jpg,png,gif" --format detailed

# Sort by modification time, newest first
fx filter ~/Documents pdf --sort-by modified --reverse

# Non-recursive search
fx filter txt --no-recursive

Options:

  • --sort-by: Sort by 'created' (creation time) or 'modified' (modification time)
  • --reverse: Reverse sort order (newest first)
  • --format: Output format (simple/detailed, default: detailed)

Output Formats:

  • simple: Just file paths
  • detailed: Includes timestamp, size, and relative time

🔍 fx ff - File Finder

Find files whose names contain a keyword, with powerful filtering options and smart exclusions. Results are printed as absolute paths and copied to the clipboard by default when run interactively (v2.13.0+), so you can paste them straight into another command or app.

# Basic usage: Find files containing "test" in their names
fx ff test

# Path-segment matching (v2.13.0+): a keyword containing "/" matches the
# relative path, not just the file name
fx ff docs/setup
fx ff frank_maintain/file-organizer.md

# Skip the clipboard copy
fx ff report --no-copy

# Find configuration files
fx ff config

# Find all Python files (using partial match)
fx ff .py

# Include normally ignored directories (.git, .venv, node_modules)
fx ff test --include-ignored

# Exclude specific directories or patterns
fx ff test --exclude build --exclude "*.log"

# Complex filtering example: find "api" files but exclude build and cache directories
fx ff api --exclude build --exclude cache --exclude "*.pyc"

# Find source files while excluding test directories
fx ff src --exclude "*test*" --exclude "*spec*"

# Case-sensitive search for specific components
fx ff Component --exclude node_modules

Real-World Use Cases:

# Development workflow: Find all TODO comments in code files
fx ff TODO --exclude node_modules --exclude .git

# Project cleanup: Find all backup files
fx ff .bak

# Debug logging: Find all log files
fx ff .log --exclude archive

# Configuration management: Find all config files across subdirectories
fx ff config --exclude backup

# Library hunting: Find specific library files
fx ff jquery --exclude node_modules --exclude dist

# Testing: Find test files but exclude coverage reports
fx ff test --exclude coverage --exclude .nyc_output

Options:

  • --include-ignored: Include .git, .venv, node_modules (default skips these heavy directories)
  • --exclude NAME: Exclude names or glob patterns; repeatable for complex filtering
  • --first: Stop after the first match (same as fx fff)
  • --no-copy: Do not copy results to the clipboard (piped/scripted output never touches the clipboard)

🔗 fx open - URL and File Launcher

Open saved URLs, local files, images, and direct targets without keeping browser tabs open.

# List saved targets with 1-based indices
fx open
fx open --all
fx open --disabled

# Open by slug or index ('o' is a shorthand alias for 'open')
fx open cc-usage
fx open 3
fx o cc-usage

# Filter the list before selecting
fx open --tag usage 2

# Copy a target to the clipboard instead of opening it
fx open copy cc-usage
fx open copy 3
fx open copy https://example.com

# Search saved targets by name, slug, tags, or target URL
fx open search usage
fx open search --tag live snooker

# Open direct targets
fx open https://example.com
fx open ./diagram.png --app Preview

# Temporarily choose a browser on macOS
fx open cc-usage --browser Firefox

# Add a new saved target; bare domains are normalized to https URLs
fx open add yahoo.co.jp --name "Yahoo! JAPAN" --slug yahoo-jp --entry-tag portal --yes

# Remove or temporarily hide saved targets
fx open delete cc-usage --yes
fx open disable cc-usage --yes
fx open enable 1 --yes

Config: fx open reads ${XDG_CONFIG_HOME}/fx-bin/open.toml or ~/.config/fx-bin/open.toml by default. Use --config ./open.toml for a custom registry.

Browser selection: Normal URL entries should omit browser and use the operating system's default browser. Add browser = "Firefox" or another macOS application name only for entries that need a dedicated browser, or use --browser for a one-off override. Explicit browser/app selection is macOS-only in v1; Linux and Windows use the OS default opener even if a portable config contains a browser field.

Mutation commands: fx open delete SELECTOR --yes permanently removes a saved target. fx open disable SELECTOR --yes hides a target from normal lists and selection without deleting it. fx open enable SELECTOR --yes restores a disabled target; numeric indices for enable come from fx open --disabled. Mutation commands preserve non-item TOML config semantically, but rewrite the registry and may remove comments or custom formatting in v1.

Search: fx open search QUERY lists enabled saved targets whose name, slug, tags, or target contains QUERY as a case-insensitive substring. Combine it with --tag to search within a tag-filtered list. Search output preserves indices from the current visible list, so fx open <index> or fx open --tag TAG <index> can open the matching enabled target. Use --all or --disabled to include or isolate disabled entries.

Copy: fx open copy SELECTOR writes the resolved target to the system clipboard instead of opening it. It accepts the same selectors as fx open (slug, 1-based index, or a direct URL/path) and honors --tag filtering. Clipboard backend: pbcopy on macOS and clip on Windows. On Linux the tool is chosen by session type — wl-copy when WAYLAND_DISPLAY is set, otherwise xclip — because Wayland and X11 keep separate clipboards and neither tool can reach the other's display server. If the preferred tool is not installed the other one is used; install wl-clipboard or xclip if neither is present.

AI metadata: fx open add TARGET --ai --yes can call the external command in FX_OPEN_AI_COMMAND. The provider may propose name, slug, and tags; normal validation still applies. The command is split into an argument vector and run with shell execution disabled; Windows provider paths with spaces should be quoted, such as "C:\Program Files\Fx AI\provider.exe" --mode json.

Options:

  • --config PATH: Use a specific TOML registry
  • --tag TAG: Filter saved targets before listing or selecting
  • --all: List enabled and disabled saved targets
  • --disabled: List only disabled saved targets
  • --browser NAME: Open URL targets with a browser on macOS, or store a macOS browser preference in fx open add
  • --app NAME: Open local files with an app on macOS, or store a macOS app preference in fx open add
  • --entry-tag TAG: Add metadata tags in fx open add
  • --ai: Ask FX_OPEN_AI_COMMAND for add metadata
  • --yes, -y: Confirm mutation commands in non-interactive mode

🔄 fx replace - Text Replacer

Replace text across multiple files with atomic write operations.

# Replace in a specific file
fx replace "old_text" "new_text" file.txt

# Replace across multiple files
fx replace "v1.0" "v2.0" *.py

# Replace in all matching files
fx replace "foo" "bar" src/*.js tests/*.js

Usage:

fx replace SEARCH_TEXT REPLACE_TEXT FILES...

Safety Features:

  • Atomic file writes prevent corruption
  • Binary files are automatically skipped
  • Reports number of replacements made per file

💾 fx backup - File Backup (NEW in v1.4.0!)

Create timestamped backups of files or directories with optional compression.

# Backup a single file
fx backup data.json

# Backup a directory with compression
fx backup my_project --compress

# Custom backup directory
fx backup config.yaml --backup-dir ./archive

# Custom timestamp format
fx backup important.txt --timestamp-format %Y-%m-%d_%H-%M

Options:

  • --backup-dir: Directory to store backups (default: 'backups')
  • --compress: Compress directory backup as .tar.xz
  • --timestamp-format: Custom strftime format for the backup timestamp

📅 fx today - Daily Workspace Manager

Create and navigate to date-organized workspace directories for daily file management.

# Navigate to today's workspace (~/Downloads/YYYYMMDD)
fx today

# Custom base directory
fx today --base ~/Projects

# Custom date format
fx today --format %Y-%m-%d  # Creates ~/Downloads/2025-09-06

# Output path for shell scripts
fx today --cd

# Dry run to see what would be created
fx today --dry-run

# Verbose output
fx today --verbose

Options:

  • --cd, -c: Output path only (for shell integration)
  • --base, -b: Base directory (default: ~/Downloads)
  • --format, -f: Date format string (default: %Y%m%d)
  • --verbose, -v: Show detailed output
  • --dry-run: Preview without creating directory

Shell Integration: With proper setup, fx today can change your shell directory:

# After running setup script
$ fx today
📅 Changed to today's workspace: /Users/you/Downloads/20250906

# Or use aliases
$ ft  # Short alias for fx today

See fx-today-setup.md for shell integration setup.

🧭 fx root - Git Project Root

Find the Git project root by searching upward for a .git directory.

fx root                  # Show root directory (with description)
cd "$(fx root --cd)"     # Jump to project root in scripts

See fx-root-setup.md for shell integration setup.

🌐 fx repo - Open GitHub Repository

Open the GitHub.com page for the Git repository containing the current directory. The command prefers origin; use --remote to select another configured remote.

fx repo                  # Open origin in the default browser
fx repo --remote fork    # Open a specific remote

Version 1 supports GitHub.com HTTPS and SSH remote URLs. If the current directory does not belong to a Git repository with a remote, the command exits without opening a browser and explains that no Git remote was found.

📍 fx realpath / fx rp - Absolute Path

Resolve a relative path, ~, or symlink to its canonical absolute path (the path must exist). The result is copied to the clipboard by default when run interactively — resolve and paste.

fx realpath .            # Current directory (result on the clipboard)
fx rp ../foo             # Relative path (alias)
fx rp ~/Downloads        # Home directory
fx rp . --no-copy        # Skip the clipboard copy

🗂️ fx organize - Date-Based File Organizer

Organize files from a source directory into date-based folders (e.g. 2026/202601/20260110/).

fx organize ~/Photos                    # Organize photos by date
fx organize ~/Downloads -o ~/Sorted     # Custom output directory
fx organize . --dry-run                 # Preview without changes
fx organize . -i "*.jpg" -i "*.png"     # Only images

📚 Usage Examples

Real-World Scenarios

1. Project Cleanup

# Find and count test files
fx files . --pattern "*test*.py"

# Identify large log files
fx size . --pattern "*.log" --limit 5 --unit MB

# Find backup files for review
fx ff .bak

2. Codebase Analysis

# Find all source files with details
fx filter "py,js,ts,jsx,tsx"

# Find TODO markers in filenames
fx ff TODO

# Update version strings in Python files
fx replace "version='1.1.0'" "version='1.2.0'" *.py

3. Data Processing

# Find recent data files
fx filter csv ./data --sort-by modified --reverse --limit 10

# Analyze dataset sizes
fx size ./datasets

4. System Maintenance

# Find log files sorted by modification time
fx filter "log,txt" /var/log --sort-by modified

# Count configuration files
fx files /etc

# Find error-related files
fx ff error

🔧 Development

Setting Up Development Environment

# Clone the repository
git clone https://github.com/frankyxhl/fx_bin.git
cd fx_bin

# Install Poetry (if not already installed)
curl -sSL https://install.python-poetry.org | python3 -
# or: pipx install poetry

# Install dependencies
poetry install --with dev

# Activate virtual environment
poetry shell

Running Tests

# Run all tests
poetry run pytest

# Run with coverage
poetry run pytest --cov=fx_bin --cov-report=html

# Run specific test file
poetry run pytest tests/test_filter.py -v

# Run security tests
poetry run pytest tests/test_*security*.py -v

Code Quality

# Format code
poetry run black fx_bin/ tests/

# Lint code
poetry run flake8 fx_bin/

# Type checking
poetry run mypy fx_bin/

# Security scan (needs the optional security group: poetry install --with security)
poetry run bandit -r fx_bin/

Building and Publishing

# Build package
poetry build

# Test installation
pip install dist/fx_bin-*.whl  # or: poetry run fx --help

# Publish to PyPI
poetry publish

🧪 Testing

fx-bin follows a comprehensive testing strategy:

Testing Methodology

  • TDD (Test-Driven Development): All features developed with tests first
  • BDD (Behavior-Driven Development): User scenarios tested with Gherkin syntax
  • Coverage: Maintaining 95%+ code coverage
  • CI/CD: Automated testing on every commit

Test Categories

  • Unit Tests: Individual function testing
  • Integration Tests: Component interaction testing
  • Security Tests: Vulnerability and safety testing
  • Performance Tests: Benchmarking and optimization
  • Edge Cases: Boundary and error condition testing

Running Different Test Suites

# Fast unit tests only
poetry run pytest -m "not slow"

# Security tests only
poetry run pytest -m security

# Integration tests
poetry run pytest -m integration

# Performance benchmarks
poetry run pytest -m performance

🔒 Security

Security Features

  • Path Traversal Protection: All file operations validate paths
  • Input Sanitization: User inputs are cleaned and validated
  • Safe Defaults: Conservative defaults prevent accidents
  • Command Injection Prevention: No shell execution with user input
  • Regular Security Audits: Automated scanning with bandit and safety

Security Testing

bandit and safety are in the optional security dependency group (not installed by poetry install --with dev). Install them first: poetry install --with security.

# Run security test suite (no extra deps needed)
poetry run pytest tests/test_*security*.py -v

# Static security analysis
poetry run bandit -r fx_bin/

# Dependency vulnerability check
poetry run safety check

Reporting Security Issues

If you discover a security vulnerability, please email frank@frankxu.me directly instead of opening a public issue.

🤝 Contributing

We welcome contributions! Here's how to get started:

Development Process

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Write tests for your feature
  4. Implement the feature
  5. Ensure all tests pass (poetry run pytest)
  6. Check code quality (poetry run black . && poetry run flake8)
  7. Commit your changes (git commit -m 'Add amazing feature')
  8. Push to the branch (git push origin feature/amazing-feature)
  9. Open a Pull Request

Guidelines

  • Follow PEP 8 style guide
  • Add tests for new features
  • Update documentation
  • Keep commits atomic and descriptive
  • Ensure CI passes before requesting review

Areas for Contribution

  • New file operation commands
  • Performance improvements
  • Documentation enhancements
  • Bug fixes
  • Test coverage improvements
  • Platform-specific optimizations

📝 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Built with Click for elegant CLI creation
  • Testing powered by pytest
  • Code formatting by Black

📞 Contact


Made with ❤️ by Frank Xu

For more information, visit the GitHub repository

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fx_bin-2.15.0.tar.gz (72.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fx_bin-2.15.0-py3-none-any.whl (73.1 kB view details)

Uploaded Python 3

File details

Details for the file fx_bin-2.15.0.tar.gz.

File metadata

  • Download URL: fx_bin-2.15.0.tar.gz
  • Upload date:
  • Size: 72.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for fx_bin-2.15.0.tar.gz
Algorithm Hash digest
SHA256 b7f6fbcf4eefffa547ec006fdc159778742cd35f9f6b59cc95c28835d2428e3e
MD5 5a481b27016ea3b2de7e809673eea0ae
BLAKE2b-256 fac21d40138c84506888377e32d51d317d90877a51a4af05caaae1168fb95b80

See more details on using hashes here.

Provenance

The following attestation bundles were made for fx_bin-2.15.0.tar.gz:

Publisher: cd-release.yml on frankyxhl/fx_bin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fx_bin-2.15.0-py3-none-any.whl.

File metadata

  • Download URL: fx_bin-2.15.0-py3-none-any.whl
  • Upload date:
  • Size: 73.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for fx_bin-2.15.0-py3-none-any.whl
Algorithm Hash digest
SHA256 550955bdc4b7755fdd84c93fa81bdbe20d39654e1fe1f4da0d93757499de06e6
MD5 83d03b66b5af9ffcf9e32ec4702ebfa2
BLAKE2b-256 c3fab9e026817998268d74e32919bc0c3a158f698e6f8cfa50a0782a6f8bd708

See more details on using hashes here.

Provenance

The following attestation bundles were made for fx_bin-2.15.0-py3-none-any.whl:

Publisher: cd-release.yml on frankyxhl/fx_bin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

2.15.0 This release

2 files

2.14.0

2 files

2.13.0

2 files

2.12.2

2 files

2.12.1

2 files

2.12.0

2 files

2.11.2

2 files

2.11.1

2 files

2.11.0

2 files

2.10.0

2 files

2.9.0

2 files

2.8.0

2 files

2.7.0

2 files

2.6.0

2 files

2.5.8

2 files

2.5.7

2 files

2.5.6

2 files

2.5.5

2 files

2.5.4

2 files

2.5.3

2 files

2.5.2

2 files

2.5.1

2 files

2.5.0

2 files

2.4.0

2 files

2.3.0

2 files

2.2.2

2 files

2.2.1

2 files

2.2.0

2 files

2.1.0

2 files

2.0.0

2 files

1.6.0

2 files

1.5.0

2 files

1.4.0

2 files

1.3.7

2 files

1.3.5

2 files

1.3.4

2 files

1.3.2

2 files

1.3.1

2 files

1.3.0

2 files

1.2.0

2 files

1.1.0

2 files

1.0.1

2 files

1.0.0

2 files

0.9.7

2 files

0.9.6

2 files

0.9.5

2 files

0.9.4

2 files

0.9.3

2 files

0.9.2

2 files

0.9.1

2 files

0.9.0

2 files

0.7.1

2 files

0.7.0

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.5

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.7

2 files

0.2.6

2 files

0.2.5

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.13

2 files

0.1.12

2 files

0.1.11

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page