我在这里有一个小问题。
如果我有两个文件,比如说filea
和fileb
,mv filea fileb
会
- 删除
fileb
- 重命名
filea
为fileb
那么如果我有两个目录,比如说dira
和dirb
,mv dira dirb
就会
- 搬入(它将
dira
成为)dirb
dirb/dira
注意到在这两种情况下都没有通知或消息,那么这对我来说非常不一致。我认为mv dira dirb
应该dirb
用内容覆盖dira
(或将两个目录合并到名为 的目录下dirb
)。
我记得在某处读过,带有斜杠的目录名称(例如dira/
)被视为目录,而不带斜杠的名称(例如dira
)被视为文件(当然,在某种程度上)。无论如何,现在我想让 shell(zsh 和可能的 bash)通过使用斜杠来尊重我的目录表示法。是否有一个终端选项可以让我强制执行此操作?
为了澄清一下,这是我想要的行为:
mv dira dirb
结果dirb
被内容覆盖dira
mv dira dirb/
结果被dira
移入dirb
(indirb/dira
)
有人和我有同样的想法吗?或者我只是很奇怪?
答案1
是的,这有点不一致,即使在 GNU 工具中也是如此。
您的提案的一个问题是无法删除非空目录。除此之外,-T
(无论如何,在 GNU 领域)近似于你想要的(第一种情况):
$ ls dira/ dirb/
dira/:
a
dirb/:
b
$ mv -iT dira/ dirb/
mv: overwrite `dirb/'? y
mv: cannot move `dira/' to `dirb/': Directory not empty
$ rm dirb/b
$ mv -iT dira/ dirb/
mv: overwrite `dirb/'? y
$ ls dira/ dirb/
ls: cannot access dira/: No such file or directory
dirb/:
a
答案2
如果您只想将所有内容从 dira 移动到 dirb 您可以运行mv dira/* dirb
。
根据我的 HP-UX 上的 mv 手册页。
The mv command moves:
+ One or more directory subtrees (directory1, [directory2, ...]) to a new or existing directory (dest-directory).
答案3
以下是获得整体更一致行为的解决方案(至少使用mv
和cp
命令)。
对于移动 ( mv
) 命令
通过使用以下选项,可以得到稍微更一致的行为-i
:
mv -i SOURCE DEST
filea
当覆盖已经存在的数据时,这会发出警告并要求确认fileb
,但在任何其他情况下都不会发出警告,也就是说,只有在数据即将丢失时才会收到警告和确认。
$ mv -i filea fileb
:
- 如果
fileb
尚不存在,filea
默默地重命名为fileb
- 如果
fileb
已经存在fileb
,在覆盖之前需要确认filea
$ mv -i dira dirb
:
- 如果
dirb
尚不存在,dira
默默地重命名为dirb
- 如果
dirb
已经存在,dira
默默地搬进dirb
永久解决方案是创建别名:$ alias mv='mv -i'
对于复制 ( cp
) 命令
对于该cp
命令,-i
存在类似的选项。但是,cp SOURCE DEST
不会表现得好像mv -i SOURCE DEST
是SOURCE
一个目录,因为如果未指定cp
该选项,则会忽略任何目录。-r
因此,要获得类似的行为,mv -i
可以使用以下命令:
$ cp -ir SOURCE DEST
这将以类似的方式处理文件和目录(如mv -i
命令所示),并在覆盖之前发出警告并要求确认。
$ cp -ir filea fileb
:
- 如果
fileb
尚不存在,filea
被默默地复制到fileb
- 如果
fileb
已经存在fileb
,在用副本覆盖之前需要确认filea
$ cp -ir dira dirb
:
- 如果
dirb
尚不存在,dira
被默默地复制到dirb
- 如果
dirb
已经存在,dira
被默默地复制到dirb
这里的永久解决方案是创建一个别名:$ alias cp='cp -ir'