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

Posted

技术标签:

【中文标题】如何通过 * 将包括隐藏文件在内的所有文件移动到父目录中【英文标题】:How to move all files including hidden files into parent directory via * 【发布时间】:2013-12-10 02:52:45 【问题描述】:

这一定是一个热门问题,但我找不到答案。

如何通过 * 移动所有文件,包括隐藏文件以及像这样的父目录:

mv /path/subfolder/* /path/

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

【问题讨论】:

这个问题有一个duplicate at SU,有一个更正确的答案(虽然不是公认的):cp -r /path/to/source/. /destination 【参考方案1】:

您可以在 UNIX 和 Linux 对How do you move all files (including hidden) from one directory to another? 的回答中找到一套全面的解决方案。它展示了 Bash、zsh、ksh93、标准 (POSIX) sh 等中的解决方案。


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

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

或一起(thanks 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/..,它们是目录和父目录(参见What do “.” and “..” mean when in a folder?)。


如果你只想复制,你可以使用一个:

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

这将复制所有文件,包括普通文件和隐藏文件,因为 /path/subfolder/. 扩展为“此目录中的所有内容”(来源:How to copy with cp to include hidden files and hidden directories and their contents?)

【讨论】:

大括号只是mv /path/subfolder/* /path/subfolder/.* /path/ 的捷径,并非绝对需要将两个命令合二为一。 我收到以下错误: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 忽略它。 . 表示当前目录,.. 表示up 目录。您一定注意到所有其他文件都被移动了。 值得一提的是大括号快捷方式不适用于所有外壳,但@chepner 命令我认为它会 “忽略警告”可能并不总是一个好主意。现在我遇到了一个脚本问题,如果任何步骤失败,我需要停止执行 - 因为这个解决方案总是会导致错误,它会杀死我的脚本。我需要一种方法来确定 mv 命令是否失败...【参考方案2】:

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

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

【讨论】:

是的,我注意到它也给出了这些错误消息,很好的发现。 我认为这是一个很好的解决方案,但很难记住这种模式 这会丢失 ..anything...anything 等文件。 - ***.com/a/31438355/2351568 包含此问题的正确正则表达式。 || 但无论如何使用shopt -s dotglob 仍然是更好的解决方案! @DylanB 不要记住它。请记住,它匹配大括号中的任何内容,用逗号分隔。 a,b* 会找到所有以 a 或 b 开头的文件,例如“解剖”和“推土机”。第二个匹配只是一个空匹配,相当于*,第一个匹配相当于.[!.],其中组[!.]表示不是以.开头的组。这意味着.*,而不是..*【参考方案3】:

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

你可以打开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 才能跳到命令。) 这也将影响所有其他命令,如 ls.. 因此可能不是你想要的,可能【参考方案4】:

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

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

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

优点是原始文件夹 (subfolder) 将作为命令的一部分被删除,当在这里使用 mv 示例时,您仍然需要清理文件夹,更不用说额外的麻烦了隐藏和非隐藏文件在一个模式中。

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

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

【讨论】:

有史以来最好的解决方案!就我而言,我刚刚删除了 -u 参数,因为我不想更新根文件夹。谢谢 这是那些命令之一,如果你不小心,你可能会在 linux 中永久地搞砸自己的事情。请更新您的答案以在 rsync 命令之前包含 sudo,否则,用户可以很容易地获得 mkdir 的权限被拒绝,但是文件删除仍然会继续进行,因此,rsync 命令将删除您要移动的整个目录,并且什么也不做.您将丢失整个目录。将 sudo 添加到答案后,这可能应该是公认的答案。所以命令应该是:sudo rsync -vuar --delete-after path/subfolder/path/ @JohnnyB 很抱歉给您带来不便。我添加了sudo--dry-run,因此人们可以在运行实际命令之前测试更改以避免任何潜在的混乱。 哦,我没有意识到有一个 --dry-run 选项。很好的补充。不需要道歉。这太棒了。【参考方案5】:

通过将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 命令一起使用可以消除所有这些问题。

【讨论】:

【参考方案6】:

让我把你介绍给我的朋友“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

最好在完成后重新打开它,否则你会混淆假设它会关闭的东西。

【讨论】:

【参考方案7】:

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

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

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

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

目标目录以/ 结尾,因为我们将源文件夹的内容作为一个整体放置到目标。

【讨论】:

虽然yes 是一个很棒的命令,如果你想覆盖目标文件,这并不总是需要的。仅当您确定要执行此操作时才使用它。另外,yes | cp ...cp -f ... 之间有区别吗?【参考方案8】:

做事

for I in $(ls -A dir)
do
mv dir/$I newDir
done

【讨论】:

【参考方案9】:

假设您在 子文件夹 运行find . -maxdepth 1 -exec mv .. \;

【讨论】:

以上是关于如何通过 * 将包括隐藏文件在内的所有文件移动到父目录中的主要内容,如果未能解决你的问题,请参考以下文章

使用 node.js 将目录中的所有文件移动到父级

ls -a 显示所有文件,包括隐藏文件。

linux 如何打包当前文件下所有文件包括隐藏文件

将 node_modules 文件夹移动到父文件夹并收到此错误

如何隐藏所有不包括文件类型的内容

如何使用PowerShell递归搜索目录中的所有文件,包括隐藏目录中的隐藏文件?