当前位置: 首页>>技术问答>>正文


我怎样才能让mv(或*通配符)移动隐藏的文件?

, ,

问题描述

我将我的主目录从旧系统迁移到新目录,并且我制作的tarball包含了所有内容,包括像.bashrc之类的隐藏文件。但是,当我将解压缩的tarball(位于/tmp)中的内容移动到我的新主目录时,隐藏文件不会复制(mv /tmp/home/rcook/* /home/rcook/)。我怎样才能让mv移动它们?

其实,我认为问题不在于mv,而在于bash的通配。如果我这样做:

mkdir a
mkdir b
touch a/.foo
touch a/bar
mv a/* b/
ls -a a/ b/

我看到这个:

a/:
.  ..  .foo

b/:
.  ..  bar

a/.foo没有移动。那么我怎样才能获得*通配符来查找隐藏的文件呢?

是的,我想我可以直接将压缩包解压缩到我的主目录中,但tarball解压缩为home/rcook/...,我想确保使用旧的定制版本覆盖新的.bashrc等,并知道如何查找和移动隐藏文件是一项有价值的技能。建议?


一些答案建议做类似mv src/.* dest/的事情。但是,我在我的测试目录中尝试了这一点,并得到错误。从…开始:

rcook$ ls -a a/ b/
a/:
.  ..  bar  .foo

b/:
.  ..
rcook$ mv a/.* b/
mv: cannot move 'a/.' to 'b/.': Device or resource busy
mv: cannot remove 'a/..': Is a directory
rcook$ ls -a a/ b/
a/:
.  ..  bar

b/:
.  ..  .foo

我究竟做错了什么?

最佳解决思路

你可以这样做 :

shopt -s dotglob
mv /tmp/home/rcook/* /home/rcook/

你可以放

shopt -s dotglob

在您的~/.bashrc中,如果您希望它成为默认值。

参见http://mywiki.wooledge.org/glob


复制点文件的另一种方法是:

mv /tmp/home/rcook/.[!.]* /home/rcook/

不要使用..*模式,因为它与..(指向父目录的指针)相匹配。如果有名称以两个点开头的文件(..something),也可以使用..?*格式。

次佳解决思路

在你的补充,你有错误,但代码仍然工作。唯一要补充的是,你告诉它只复制点文件。尝试:

mv src/* src/.* dst/

你仍然会得到错误。和..条目,这很好。但此举应成功。

~/scratch [andrew] $ mv from/* from/.* to/
mv: cannot move ‘from/.’ to ‘to/.’: Device or resource busy
mv: cannot remove ‘from/..’: Is a directory
~/scratch [andrew] $ ls -a from/ to/
from/:
.  ..

to/:
.  ..  test  .test

第三种解决思路

如果您在目录中使用ls -l,则会在列出的文件中看到...。所以,我认为mv .* /dest将这些指标考虑在内。尝试:

mv /tmp/home/rcook/{*,.[^.]*,..?*} /home/rcook/

这会忽略当前和父目录指针。

如果*[^.]*..?*三种模式中的任何一种与任何文件都不匹配,您将收到错误,因此您应该只包含匹配的文件。

第四种思路

我能想到两种可能的解决方案。首先是使用cp而不是递归选项,将当前目录复制到目标。

cp -Rp . /desired/directory

那么你可以删除当前目录中的源文件

另外,如果你知道这些文件是明确命名的(没有空格,通配符,non-printable字符),你可以做这样的事情

mv $(ls -A) /desired/directory

第五种思路

Linux上没有”hidden”文件。默认情况下,以点开头的文件只会隐藏文件列表。

要使用glob复制文件,需要在文件前加上.(如mv -u .* foo),然后.foo将在移动时显示为foo/.foo

-u选项只会在源文件较新或目标文件丢失时移动文件。或者你可以忽略关于移动...的错误,因为它们是特殊文件,无法移动,但会被shell中的.* glob捕获。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/695.html,未经允许,请勿转载。