move-item — PowerShell's move/rename cmdlet — the mv equivalent across all 5 shells
Equivalents in every shell
mv source destPOSIX `mv` renames within a filesystem (atomic) and copies+deletes across filesystems. `-i` prompts on overwrite, `-n` skips existing, `-v` prints each rename. No built-in undo. Trailing `/` on `dest` enforces "must be a directory" semantics.
mv source destSame `/bin/mv`. zsh adds `zmv` (autoload via `autoload -U zmv`) — pattern-based bulk rename: `zmv '(*).log' '$1.txt'`. zmv is dry-run with `-n`; this is the killer feature for batch renames.
mv source destSame external `mv`. Fish has no built-in batch rename; the idiom is `for f in *.log; mv $f (string replace .log .txt $f); end`.
Move-Item -Path source -Destination destPowerShell-native cmdlet (aliases `mv`, `move`, `mi`). Works across PS providers — file system, registry, certificate store. `-Force` overwrites read-only destinations; `-Confirm` prompts; `-WhatIf` dry-runs. Wildcards on `-Path`, single literal on `-Destination`.
move source destBuilt-in `move`. Renames within a drive (atomic) and copies+deletes across drives. `/Y` suppresses overwrite prompt; `/-Y` forces the prompt. `ren oldname newname` is the rename-only variant — same drive, no path change. Wildcards work on the source but the destination must be a single name pattern.
Worked examples
Rename a single file
mv old.txt new.txtmv old.txt new.txtMove-Item old.txt new.txtren old.txt new.txtMove all .log files to a backup folder, overwriting existing
mv -f *.log backup/Move-Item -Path *.log -Destination backup\ -Forcemove /Y *.log backup\Dry-run a bulk move (preview without executing)
zmv -n '(*).log' '$1.bak'Move-Item -Path *.log -Destination *.bak -WhatIfGotchas
- `Move-Item -Destination` does NOT accept a directory path with a trailing `\` to mean 'into here' the way Unix `mv source dir/` does. If `dest` exists as a directory, `Move-Item source dest` moves into it; if `dest` does not exist, it RENAMES `source` to `dest`. The trailing-slash trick that prevents accidental rename in mv (`mv file dir/`) has no equivalent — explicit `Test-Path dest -PathType Container` is the safe form.
- Cross-volume moves are not atomic on either side: `mv` and `Move-Item` both fall back to copy+delete when source/dest live on different filesystems / drives. A power loss mid-move can leave the source intact and the dest partial; treat cross-volume moves as conceptually `cp + rm`. For atomic on Linux, `rename(2)` is same-fs only.
- `Move-Item` cannot move a file to a different PROVIDER (e.g. file system → registry). The error is `Source and destination paths must be of the same provider type` — surprising the first time. To bridge providers, `Get-Item source | ForEach-Object { Set-Item -Path dest -Value $_.Value }` is the manual pattern.
- PowerShell wildcards in `-Path` follow PowerShell glob semantics, NOT regex. `Move-Item *.log archive\` works; `Move-Item ^.*\.log$ archive\` does NOT (regex is not supported on Path). For regex selection, pipe: `Get-ChildItem | Where-Object Name -Match '^app.*\.log$' | Move-Item -Destination archive\`.
- cmd `move *.log subdir\` succeeds if `subdir` exists, but if `subdir` does NOT exist, `move *.log subdir` (no trailing `\`) RENAMES the first match to `subdir` and ERRORS on the rest. Always end the destination with `\` when you mean a directory; this is the most common cmd `move` gotcha.