For a single file, you can use brace expansion to construct a command line to rename a file, where only one part of the file name changes.
mv /Users/dir/dir1/moredir/long/foo.{txt,yaml}
The general syntax is mv UNCHANGED1{OLD,NEW}UNCHANGED2
, which expands to mv UNCHANGED1OLDUNCHANGED2 UNCHANGED1NEWUNCHANGED2
before running mv
.
For multiple files, the zsh function zmv
provides convenient ways to move and rename files. Put this in your .zshrc
, or run it from the command line in each session where you want to use zmv
:
autoload -zU zmv
Then, to change the extension of files in the current directory, you can run any of these. Note that you need single quotes around the arguments, because the *
and $
need to be interpreted inside zmv
and not before invoking zmv
.
zmv '*.txt' '$f:r.yaml'
zmv '(*).txt' '$1.yaml'
zmv -w '*.txt' '$1.yaml'
zmv -W '*.txt' '*.yaml'
To change the extension of files in another directory, without having to repeat the directory path:
zmv '/Users/dir/dir1/moredir/long/*.txt' '$f:r.yaml'
(cd /Users/dir/dir1/moredir/long && zmv '(*).txt' '$1.yaml')
(cd /Users/dir/dir1/moredir/long && zmv -w '*.txt' '$1.yaml')
(cd /Users/dir/dir1/moredir/long && zmv -W '*.txt' '*.yaml')
In the replacement text:
$f
is the whole source path.
:r
is a history modifier which removes the extension from the file name.
$1
is the first group in parentheses in the source pattern. Groups in parentheses can't contain directory separators (with one exception that doesn't apply here).
- The
-w
flag automatically puts each wildcard in a group.
- The
-W
flag causes each *
in the replacement text to stand for whatever the corresponding *
matches in the source pattern.
(There are several other tools to do that, but they're not part of the default installation on most Unix variants including macOS. Since you're using zsh, take advantage of zmv, which is pretty good at its job.)
autoload -zU zmv
instead ofautoload -XU zmv
? – Stéphane Chazelas Sep 21 '22 at 05:56copy-prev-word
zle widget). – Stéphane Chazelas Sep 21 '22 at 05:58(){mv $1 $1:r.yaml} long-string...
– Stéphane Chazelas Sep 21 '22 at 06:00