mv
mv(move)用于移动文件和目录,也用于重命名 —— 在 Linux 里这两件事是同一个操作。
mv [选项] 源 目标mv [选项] 源... 目标目录目标不存在则是重命名,目标是已存在的目录则是移动进去 给多个源时,最后一个参数必须是已存在的目录 移动目录不需要
-r,这一点和 cp 不同
同一个文件系统内,mv 只是改目录项(调 rename),inode 和数据块原地不动,所以移动一个 100 GB 的文件也是瞬间完成的。
跨文件系统时没有这条捷径,mv 退化成「复制到新位置 + 删除源文件」:
- 耗时与文件大小成正比
- 中途断电或 Ctrl-C,目标位置会留下一个不完整的文件
- inode 号会变,指向源文件的硬链接不会跟过去
df /home /mnt/usb # 两条路径不在同一个文件系统上,就是跨盘搬运| 选项 | 说明 |
|---|---|
-i |
覆盖前提示(interactive) |
-n |
目标已存在就跳过,不提示(no-clobber) |
-f |
直接覆盖,不提示(force),默认行为 |
-u |
只在源比目标新、或目标不存在时才移动(update) |
-v |
打印每一次移动(verbose) |
-b |
覆盖前先备份,被覆盖的文件加 ~ 后缀(backup) |
-t <目录> |
显式指定目标目录,目录写在前面(target) |
-T |
把目标当作普通文件处理,不当成「移进这个目录」 |
1. 重命名
mv old.txt new.txtmv olddir newdir2. 移动到目录
mv a.txt b.txt /tmp/mv -t /tmp/ a.txt b.txt # 目标在前-t 的用处是配合 xargs,因为 xargs 只会往命令末尾追加参数:
find . -name '*.log' -print0 | xargs -0 mv -t /tmp/logs/3. 目标已存在时的歧义
mv src dst
dst不存在:把src重命名成dstdst是已存在的目录:变成dst/src只想要前一种语义,加-T把歧义关掉:mv -T src dst
4. 文件名以 - 开头
mv -- -weird.txt normal.txtmv ./-weird.txt normal.txt
-开头的参数会被当成选项,--表示选项到此为止,或者给个./前缀
5. mv 做不了批量改名
mv *.txt *.md # 不会按预期工作通配符是 shell 展开的,mv 收到的是一串文件名,没有「模式替换」这回事 批量改名用
rename,或者 for 循环配${var%.txt}这类参数展开
man mv- GNU Coreutils – mv