如何通过 * 将包括隐藏文件在内的所有文件移动到父目录中
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 .. \;
【讨论】:
以上是关于如何通过 * 将包括隐藏文件在内的所有文件移动到父目录中的主要内容,如果未能解决你的问题,请参考以下文章