如何通过*将所有文件(包括隐藏文件)移动到父目录中


113

它一定是一个很普遍的问题,但我找不到答案。

如何通过*将所有文件(包括隐藏文件)移动到父目录,如下所示:

mv /path/subfolder/* /path/

这会将所有文件移到预期的父目录中,但不会移动隐藏文件。怎么做?


1
这个问题在SU重复,甚至有一个更正确的答案(虽然不是公认的答案): cp -r /path/to/source/. /destination
Florian 2015年

Answers:


202

您可以在UNIX和Linux关于如何将所有文件(包括隐藏文件)从一个目录移动到另一个目录的答案中找到一套全面的解决方案。它显示了Bash,zsh,ksh93,标准(POSIX)sh等解决方案。


您可以同时使用这两个命令:

mv /path/subfolder/* /path/   # your current approach
mv /path/subfolder/.* /path/  # this one for hidden files

或一起(感谢pfnuesel):

mv /path/subfolder/{.,}* /path/

扩展为:

mv /path/subfolder/* /path/subfolder/.* /path/

(示例:echo a{.,}b扩展为a.b ab

请注意,这将显示一些警告:

mv: cannot move ‘/path/subfolder/.’ to /path/.’: Device or resource busy
mv: cannot remove /path/subfolder/..’: Is a directory

只需忽略它们即可:这是因为/path/subfolder/{.,}*还会扩展到/path/subfolder/./path/subfolder/..,它们是目录和父目录(请参阅“。”和“ ..”在文件夹中的含义是什么?)。


如果您只想复制,则可以使用:

cp -r /path/subfolder/. /path/
#                     ^
#                     note the dot!

这将复制所有文件,包括普通文件和隐藏文件,因为/path/subfolder/.扩展到“此目录中的所有内容”(来源:如何使用cp复制以包括隐藏文件和隐藏目录及其内容?


2
花括号只是的捷径mv /path/subfolder/* /path/subfolder/.* /path/,并不是将两个命令组合为一个的严格要求。
chepner 2013年

7
我收到以下错误:mv: overwrite `/path/.'? y mv: cannot move `/path/subfolder/.' to `/path/.': Device or resource busy mv: overwrite `/path/..'? y mv: cannot move `/path/subfolder/..' to `/path/..': Device or resource busy
Dejan 2014年

@Dejan只需忽略它。.表示当前目录,..表示up目录。您必须已经注意到所有其他文件都已移动。
Debiprasad

值得一提的是,括号快捷方式将所有的炮弹没有工作,但@chepner命令我认为它会
赫苏斯·卡雷拉

7
“仅忽略警告”可能并不总是一个好主意。现在,我遇到了脚本问题,如果有任何步骤失败,我需要停止执行-因为此解决方案始终会导致错误,因此会终止我的脚本。我需要一种方法来确定mv命令是否失败...
MarioVilas

29

我认为这是最优雅的,因为它也不会尝试移动..

mv /source/path/{.[!.],}* /destination/path

1
是的,我注意到它也提供了这些错误消息,很好的发现。
约瑟夫·阿斯特拉罕

我认为这是一个很好的解决方案,但很难记住这种模式
Dylan B

这会丢失诸如..anything...anything等文件。- stackoverflow.com/a/31438355/2351568包含用于此问题的正确正则表达式。|| 但是无论如何,使用shopt -s dotglob仍然是更好的解决方案!
DJCrashdummy18年

@DylanB不要记住它。请记住,它与花括号中的内容匹配,并用逗号分隔。{a,b}*会找到所有以a或b开头的文件,例如“ anatomy”和“ bulldozer”。第二个匹配项只是一个空匹配项,等效于*,而第一个匹配项则等效于.[!.],其中组[!.]表示的组不是以开头的.。这意味着.*但不是..*
mazunki

28

这会将所有文件移到预期的父目录中,但不会移动隐藏文件。怎么做?

您可以打开dotglob

shopt -s dotglob               # This would cause mv below to match hidden files
mv /path/subfolder/* /path/

要关闭dotglob,您需要说:

shopt -u dotglob

很有帮助。想要了解更多信息,但是shopt是内置的,因此man shopt不起作用,而且help shopt非常简短。但是您可以这样做bashman () { man bash | less -p "^ $1 "; },然后bashman shopt直接阅读所有内容。(如我所发现的,如果有行以shopt开头,则可能必须按n键才能跳到该命令。)
Nick Rice

2
这也将影响所有其他命令,例如ls..因此可能不是您想要的,这可能是
phil294

5

另一种更简单的解决方案是使用rsync实用程序:

sudo rsync -vuar --delete-after --dry-run path/subfolder/ path/

注意:以上命令将显示要更改的内容。要执行实际更改,请删除--dry-run

优点是原始文件夹(subfolder)以及命令的一部分也将被删除,并且在mv此处使用示例时,您仍然需要清理文件夹,更不用说将单个文件包含隐藏和非隐藏文件的麻烦了。模式。

此外rsync,它还提供了在遥控器之间复制/移动文件的支持,并且可以确保复制的文件与原始文件(-a)完全一样。

使用的-u参数将跳过现有的较新文件,-r递归到目录中,并-v会增加详细程度。


有史以来最好的解决方案!就我而言,我只是删除了-u参数,因为我不想更新根文件夹。谢谢
Thales Ceolin 2015年

这是其中的一些命令之一,如果您不小心的话,就可以永久地在linux中自行搞乱。请在rsync命令之前更新您的答案以包含sudo,否则,用户可以轻松获得mkdir的权限被拒绝,但是文件删除仍然会继续进行,因此,rsync命令将删除您想要移动的整个目录,并且什么也不做。您将丢失整个目录。将sudo添加到答案后,这可能应该是可接受的答案。所以命令应该是:sudo rsync -vuar --delete-after path / subfolder / path /
Blue Water

@JohnnyB抱歉给您带来不便。我添加了sudo--dry-run,因此人们可以在运行实际命令之前测试所做的更改,以避免任何潜在的混乱。
kenorb

哦,我没有意识到有--dry-run选项。很好的补充。无需道歉。太好了
Blue Water

3

让我向您介绍我的朋友“ dotglob”。无论“ *”是否包含隐藏文件,它都会打开和关闭。

$ mkdir test
$ cd test
$ touch a b c .hidden .hi .den
$ ls -a
. ..  .den  .hi .hidden a b c

$ shopt -u dotglob
$ ls *
a b c
$ for i in * ; do echo I found: $i ; done
I found: a
I found: b
I found: c

$ shopt -s dotglob
$ ls *
.den  .hi .hidden a b c
$ for i in * ; do echo I found: $i ; done
I found: .den
I found: .hi
I found: .hidden
I found: a
I found: b
I found: c

默认为“关闭”。

$ shopt dotglob
dotglob         off

最好在完成后将其重新打开,否则您会以为将其关闭会感到困惑。


3

通过将find命令与命令结合使用mv,可以防止mv命令尝试移动目录(例如...)和子目录。这是一个选择:

find /path/subfolder -maxdepth 1 -type f -name '*' -exec mv -n {} /path \;

提供的其他一些答案有问题。例如,以下每个操作都将尝试从源路径移动子目录:

1) mv /path/subfolder/* /path/ ; mv /path/subfolder/.* /path/
2) mv /path/subfolder/{.,}* /path/ 
3) mv /source/path/{.[!.],}* /destination/path

此外,2)包括。和..文件,以及3)丢失了..foobar,... barfoo等文件。

您可以使用,mv /source/path/{.[!.],..?,}* /destination/path其中将包含3)遗漏的文件,但仍会尝试移动子目录。如上文所述,将该find命令与命令配合使用可mv消除所有这些问题。


2

当我必须将所有文件(包括.文件)复制保留权限的目标目录时,针对此问题的解决方案是:(如果已存在,则覆盖)

yes | cp -rvp /source/directory /destination/directory/

yes用于自动覆盖目标文件, r递归, v详细, p保留权限。

请注意,源路径不是以结尾/(因此,所有文件/目录和。文件都被复制了)

/当我们将源文件夹的内容放置到整个目标位置时,目标目录以结尾


yes如果要覆盖目标文件,虽然使用了一个很棒的命令,但这并不总是需要的。仅在确定要执行此操作时才使用它。另外,yes | cp ...和之间有区别cp -f ...吗?
mazunki
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.