How to replace an old sku prefix across a product csv
- Step 1Confirm the exact old and new prefixes — Decide the literal boundary, e.g. old
OLD-to newNEW-. Check whether the dash is part of the prefix; getting this wrong is the usual source of a broken suffix. - Step 2Export the product or inventory CSV — Download from your ERP, WMS, PIM, or store. The dropzone accepts
.csv,.tsv,.txtwith auto delimiter detection. - Step 3Turn on Regex mode and anchor the prefix — Tick Regex mode. Find
^OLD-, Replace withNEW-. The^anchor means the match only fires when the cell value starts withOLD-, so a barcode containingOLD-mid-string is safe. - Step 4Run and verify the counter against your SKU count — Click Replace. Replacements made should equal the number of cells that started with the old prefix — cross-check it against how many SKUs you expected to migrate.
- Step 5Repeat for each file in the migration — Run the same anchored pass on the order CSV, inventory snapshot, and feed. Identical Find/Replace keeps the prefix consistent across every system.
- Step 6Download and distribute the updated files — Click Download CSV (saved as
<name>.replaced.csv) and import each into its system. Re-export and spot-check a few SKUs to confirm prefix swapped, suffix unchanged.
Prefix-swap patterns — literal vs anchored
How the same prefix swap behaves with Regex off (literal substring) versus on (anchored). Anchoring is what keeps the swap a true prefix replacement.
| Find | Regex mode | Matches | Result on `OLD-12-OLD-9` |
|---|---|---|---|
| OLD- | Off (literal) | Every OLD- in the cell | NEW-12-NEW-9 (both replaced) |
| ^OLD- | On | Only a leading OLD- | NEW-12-OLD-9 (suffix's OLD- kept) |
| OLD-(\d+) | On | OLD- + digits anywhere | NEW-12-NEW-9 (both, but digit-bounded) |
| ^OLD-(?=\d) | On | Leading OLD- before a digit | NEW-12-OLD-9 (lookahead, safe) |
Migration checklist across systems
Run the identical anchored pass on every file a SKU rename touches. The tool's option set is the same in each case.
| File | Find (Regex on) | Replace with | Watch out for |
|---|---|---|---|
| Product feed | ^OLD- | NEW- | Variant rows may repeat the prefix in a parent-SKU column |
| Inventory snapshot | ^OLD- | NEW- | Barcode/EAN columns that contain OLD- mid-string — anchor protects them |
| Order export | ^OLD- | NEW- | Historical orders may need the old SKU kept for audit — migrate a copy |
| Supplier mapping | ^OLD- | NEW- | Cross-reference column may pair old↔new; don't rewrite the 'old' side |
Cookbook
Before/after SKU cells from real product and inventory exports. Anchored regex keeps the swap to the prefix only; the header row is preserved.
True prefix swap with the ^ anchor
ExampleThe anchored pattern ^OLD- only matches at the start of a cell, so the numeric suffix is untouched and a OLD- appearing later in the value (rare, but it happens in compound SKUs) is preserved.
Input: SKU,Name OLD-12345,Widget A OLD-99000,Widget B KIT-OLD-7,Bundle Find (Regex ON): ^OLD- Replace with: NEW- Output: SKU,Name NEW-12345,Widget A NEW-99000,Widget B KIT-OLD-7,Bundle (mid-string OLD- preserved) Replacements made: 2
Literal pass over-replaces a compound SKU
ExampleShows why the anchor matters. With Regex off, Find OLD- is a global substring match — it replaces every OLD-, including the one inside KIT-OLD-7, which you probably didn't intend.
Input: SKU KIT-OLD-7 Find: OLD- (Regex OFF) Replace with: NEW- Output: SKU KIT-NEW-7 (mid-string replaced too) Use ^OLD- in Regex mode to avoid this.
Some SKUs already use the new prefix
ExampleA partially-migrated file already has NEW- rows. The Find ^OLD- simply doesn't match them, so they pass through unchanged. Running the pass twice is harmless.
Input: SKU NEW-001 OLD-002 Find (Regex ON): ^OLD- Replace with: NEW- Output: SKU NEW-001 (unchanged) NEW-002 Replacements made: 1
Header reading 'OLD SKU' is protected
ExampleDuring a migration you might keep a column literally headed OLD SKU. Because row 0 is never processed, the heading survives while the values migrate.
Input: OLD SKU,New SKU OLD-100, OLD-101, Find (Regex ON): ^OLD- Replace with: NEW- Output (header untouched): OLD SKU,New SKU NEW-100, NEW-101, Replacements made: 2
Change a numeric padding format, not just the prefix
ExampleIf the rename also adds zero-padding, a capture group rewrites the suffix. Regex captures the digits; the replacement references them with $1.
Input: SKU OLD-5 OLD-42 Find (Regex ON): ^OLD-(\d+)$ Replace with: NEW-$1 Output: SKU NEW-5 NEW-42 (Note: the tool can't compute zero-padding; for fixed-width formatting use a spreadsheet or [csv-cleaner](/tool/csv-cleaner) after the prefix swap.)
Errors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
Literal Find replaces the prefix everywhere, not just at the start
By designWith Regex mode OFF, Find OLD- matches every occurrence in a cell (global match), so a compound SKU like KIT-OLD-7 becomes KIT-NEW-7. Fix: use Regex mode and anchor with ^OLD- so only a leading prefix is swapped and the suffix is left intact.
Barcode column contains the prefix string
By designThere is no column selector, so a literal OLD- would also match inside an EAN/barcode or a description that happens to contain those characters. Fix: anchor with ^OLD- (start of cell) — barcodes are unlikely to start with your SKU prefix, so they're protected. To truly limit by column, isolate rows with csv-column-filter first.
Suffix accidentally altered by a too-broad Find
By designFind OLD (without the dash, Regex off) would turn OLD-12OLD9 into NEW-12NEW9 and could even hit the letters OLD inside a product name. Fix: include the boundary character (OLD-) and anchor it (^OLD-); test on a small sample and read the replacements counter before trusting the full file.
Header row never migrates
PreservedRow 0 is returned unchanged, so a SKU / Variant SKU / merchant-sku / OLD SKU heading is safe. If your inventory file has no header row, the first SKU row is treated as a header and skipped — prepend a placeholder header.
Already-new SKUs are skipped
Expected^OLD- doesn't match cells that already start with NEW-, so a partially-migrated file is handled correctly and the pass is idempotent. The replacements counter reflects only the still-old SKUs that changed.
Invalid regex returns the file unchanged
No changesA malformed anchored pattern (e.g. an unclosed group ^OLD-(\d+) is caught and the original rows are returned with 0 replacements. Fix: if the counter is 0 when you expected matches, check the regex — a missing closing paren in a capture group is the usual cause.
One file at a time — no batch across systems in one click
By designEach run processes one uploaded file. To migrate the feed, order export, and inventory snapshot you upload and run each separately (the Find/Replace stays identical). For repeatable multi-file runs, the @jadapps/runner can script the same pass per file.
Free tier limit on a large inventory export
Tier limitFree caps at 2 MB / 500 rows; a full WMS inventory dump exceeds it. Fix: upgrade to Pro to lift the limits, or split with csv-row-splitter, swap the prefix in each chunk with the identical pass, then recombine with csv-merger.
Frequently asked questions
Will this replace the prefix only, not the whole SKU?
Only if you anchor it. With Regex mode on and Find ^OLD-, the match fires only at the start of the cell, so OLD-12345 becomes NEW-12345 and the 12345 suffix is untouched. With Regex off, Find OLD- is a substring match and replaces every OLD- in the cell — use the anchor for a true prefix swap.
What if some SKUs already use the new prefix?
They're skipped. ^OLD- doesn't match a cell that starts with NEW-, so a half-migrated file is handled cleanly and the pass is safe to re-run. The replacements counter shows only the cells that actually changed.
Can I replace prefixes in the SKU and barcode columns in one run?
The replacement already runs across the whole file — there's no per-column scoping — so both columns are processed in one pass. The risk is matching a barcode that contains your prefix string; anchoring with ^OLD- protects barcodes because they rarely start with a SKU prefix. To strictly target one column, pre-filter with csv-column-filter.
How do I avoid changing `OLD-` inside a compound SKU like `KIT-OLD-7`?
Use the ^OLD- anchor in Regex mode. It only matches a leading prefix, so the OLD- in the middle of KIT-OLD-7 is preserved. A literal (non-anchored) Find would replace both occurrences.
Can I rewrite the numeric suffix at the same time, e.g. add padding?
Partly. A capture-group pattern like Find ^OLD-(\d+)$ Replace with NEW-$1 carries the digits across, but the tool can't compute zero-padding or arithmetic — it only substitutes text. For fixed-width formatting, do the prefix swap here, then format the suffix in a spreadsheet.
Does case matter for the prefix?
By default no — matching is case-insensitive, so old-, Old-, and OLD- all match a single Find. The replacement is written exactly as typed, normalising the casing. Tick Case sensitive if a lowercase old- means something different in your data.
Will my SKU or barcode header get rewritten?
No. The header row (row 0) is never modified, so headings like SKU, Variant SKU, or even a literal OLD SKU column are preserved. Note that a headerless file will have its first SKU row skipped — add a placeholder header if needed.
How do I confirm the swap was correct before distributing?
Check the Replacements made count against the number of SKUs you expected to migrate, and eyeball the first-10-rows preview. For a deeper check, run csv-validator or csv-duplicate-finder to ensure no two SKUs collided after the rename.
What file types and sizes are supported?
.csv, .tsv, and .txt, with delimiter auto-detection. Free tier handles up to 2 MB / 500 rows; Pro removes both limits. For large inventory dumps, split with csv-row-splitter and recombine with csv-merger.
Is my inventory data uploaded anywhere?
No. PapaParse runs in your browser; SKUs, barcodes, and stock counts never reach a JAD server. Only an anonymous run counter is stored server-side for signed-in dashboard stats, and you can opt out in account settings.
I need to run the same swap on five files — is there a faster way than uploading each?
For repeatable runs, pair the @jadapps/runner: GET /api/v1/tools/csv-find-replace returns the option schema, then POST each file to 127.0.0.1:9789/v1/tools/csv-find-replace/run with the same {find:'^OLD-', replace:'NEW-', useRegex:true} payload. A migration script loops the runner over every export.
Can I keep the old SKU for audit while migrating?
Yes — work on a copy. Migrate the active files with the prefix swap, but keep an untouched original (or duplicate the SKU into an Old SKU column first using csv-column-merger or a copied column) so historical orders remain traceable to the original identifier.
Privacy first
Processing runs locally in your browser with PapaParse. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.