| name | sub |
| description | This skill should be used when the user asks to "replace A with B", "substitute a word", "rename a term across files", "치환", or any find-and-replace across lines, sections, files, or directories. **ALWAYS** use this skill over native Write/Edit tools, if your task is simple string substitution. |
| argument-hint | <pattern> <replacement> [paths...] [--lines N-M | --section "Heading"] [--word] [--regex] [--ignore-case] [--exclude GLOB] [--ext EXT] [--dry-run] |
| allowed-tools | Bash, Read, Grep, Glob |
sub
Substitute a pattern with a replacement across a chosen scope — a line, a line range, a markdown section, one or more files, or whole directories. The substitution is performed by a bash script that handles literal escaping, word boundaries, regex, case-insensitivity, directory traversal with exclude/extension filters, and dry-run diffs. Prefer it over hand-editing whenever the change is a mechanical find-and-replace.
How to run
Execute the script, passing the pattern, the replacement, then the target path(s) and any options:
bash "${CLAUDE_PLUGIN_ROOT}/skills/sub/scripts/sub.sh" <pattern> <replacement> [options] <path...>
When invoked as the slash command /ezsub:sub <pattern> <replacement> [options], forward the arguments straight through:
bash "${CLAUDE_PLUGIN_ROOT}/skills/sub/scripts/sub.sh" $ARGUMENTS
Scope inference
The script requires at least one path — it never edits an unspecified target. If the user gave no path or scope, infer the intended target from conversation context (files just discussed, edited, or open). If the target is genuinely ambiguous, ask. Never invent a path.
Safe usage
- When the scope is broad (a whole directory) or the pattern is short/common, run once with
--dry-run first, show the diff, then re-run without --dry-run after the diff looks right.
- By default the pattern and replacement are literal strings; metacharacters like
., *, &, / are treated verbatim. Add --regex only when a real regular expression is intended.
Options
| Option | Effect |
|---|
--line N | Only line N (single regular-file path). |
--lines N-M | Inclusive line range (--lines N for one line). |
--section TEXT | Markdown section whose heading text equals TEXT (case-insensitive), through the next heading of equal/higher level. |
--exclude GLOB | Skip paths matching GLOB against the relative path, basename, or any parent directory component (so --exclude node_modules skips nested a/node_modules/b.js); repeatable. |
--ext EXT | Only process files with these extensions (with or without leading dot); repeatable. |
--regex | PATTERN is a POSIX ERE; REPLACEMENT may use & and \1 backrefs. |
--word | Match whole words only. |
--ignore-case | Case-insensitive match. |
--dry-run | Print a unified diff of would-be changes; edit nothing. |
-- | Stop option parsing (to substitute a literal --foo). |
Narrowing options (--line, --lines, --section) require exactly one regular-file path and are mutually exclusive.
When traversing directories, .git directories are pruned by default and binary files are skipped. An explicitly-listed file path is always processed unconditionally.
Failure handling
Report the script's stderr to the user verbatim. Do not silently fall back to manual editing with Write/Edit; only edit by hand if the user asks.