外壳:zsh
大家好,我正在尝试像在 DOS 中一样快速更改文件的文件扩展名。
我确实发现了这个问题(某种程度上)它仍然没有回答这个问题: 使用 mv 重命名多个文件以更改扩展名
我想更改远离我的特定目录上的文件的扩展名,pwd
因此当我这样做时,mv
我不想再次重新输入同一目录,即:
mv /Users/dir/dir1/moredir/long/foo.txt /Users/dir/dir1/moredir/long/foo.yaml
像我这样的 n00b 会简单地假设你可以去 /Users/dir/dir1/moredir/long/foo.txt *.yaml ,但事实并非如此。
有什么简单的方法可以实现这一目标吗?
提前感谢,祝您周末愉快!
答案1
对于单个文件,您可以使用大括号扩展构造一个命令行来重命名文件,其中仅文件名的一部分发生变化。
mv /Users/dir/dir1/moredir/long/foo.{txt,yaml}
一般语法是, 扩展为before running 。mv UNCHANGED1{OLD,NEW}UNCHANGED2
mv UNCHANGED1OLDUNCHANGED2 UNCHANGED1NEWUNCHANGED2
mv
对于多个文件,zsh 函数zmv
提供移动和重命名文件的便捷方法。将其放入您的中.zshrc
,或者在您要使用的每个会话中从命令行运行它zmv
:
autoload -zU zmv
然后,要更改当前目录中文件的扩展名,您可以运行其中任何一个。请注意,参数需要用单引号引起来,因为*
and$
需要在内部解释zmv
,而不是在调用之前解释zmv
。
zmv '*.txt' '$f:r.yaml'
zmv '(*).txt' '$1.yaml'
zmv -w '*.txt' '$1.yaml'
zmv -W '*.txt' '*.yaml'
要更改另一个目录中文件的扩展名,而不必重复目录路径:
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')
在替换文本中:
$f
是整个源路径。:r
是一个历史修改器这会从文件名中删除扩展名。$1
是源模式中括号中的第一组。括号中的组不能包含目录分隔符(有一个例外,此处不适用)。- 该
-w
标志自动将每个通配符放入一个组中。 - 该
-W
标志使*
替换文本中的每个内容代表*
源模式中相应的匹配项。
(还有其他几个工具可以做到这一点,但它们不是大多数 Unix 变体(包括 macOS)上默认安装的一部分。由于您使用的是 zsh,所以请利用 zmv,它的工作非常出色。)
答案2
要将单个文件重命名foo.txt
到foo.yaml
目录中/Users/dir/dir1/moredir/long
,您可以首先进入该目录,然后运行mv
:
cd /Users/dir/dir1/moredir/long
mv foo.txt foo.yaml
cd - # to move back to the original working directory
或者,您可以使用大括号扩展来扩展到源路径名和目标路径名:
mv /Users/dir/dir1/moredir/long/foo.{txt,yaml}
上面将扩展为完整命令
mv /Users/dir/dir1/moredir/long/foo.txt /Users/dir/dir1/moredir/long/foo.yaml
...在 shell 调用之前mv
。显然,只有当文件在重命名后应保留在同一目录中时,这才有效。