Skip to main content

Refactoring & Search-Replace

A common task in software development is renaming a variable, class, or function across hundreds of files.

While sed is the standard tool for string replacement, it is not great at finding files. fd is the perfect frontend for sed, feeding it the exact files that need modification.

1. The Standard sed Pipeline

To perform a search-and-replace across a project, we use fd to find the target files, and xargs to pass those files to sed -i (in-place editing).

# Replace "old_function" with "new_function" in all Python files
fd -e py -0 | xargs -0 sed -i 's/old_function/new_function/g'

Why this is safe:

  • fd -e py ensures we only touch Python files (ignoring binaries, JSON, etc., which sed might corrupt).
  • -0 and xargs -0 ensure the pipeline won't break if a file is named script version 2.py.
  • .gitignore is automatically respected, so we don't accidentally modify library code inside venv/ or site-packages/.

2. Using sd (The Modern Alternative)

Just as fd is a modern alternative to find, sd is a modern Rust alternative to sed. It uses simple string replacement or standard regex instead of the cryptic s/old/new/g syntax.

If you have sd installed, the workflow is even cleaner.

# Using `sd` via fd's batch execution (-X)
fd -e ts -X sd "import \{ OldComponent \}" "import { NewComponent }"

3. Renaming Files with rename

Sometimes you need to rename the files themselves, not just their contents. fd pairs perfectly with the Perl rename utility.

# Rename all .jpeg files to .jpg
fd -e jpeg -x rename 's/\.jpeg$/.jpg/' {}

4. Unzipping Multiple Archives

If you download a dataset containing dozens of .zip files, fd can extract them all efficiently.

# Unzip all files, placing their contents in the same directory as the zip
fd -e zip -x unzip -q {} -d {//}

(Recall that {//} is the fd placeholder for the parent directory of the matched file).