如何将所有文件从当前目录移动到上层目录?


Answers:


202

您正在寻找的命令是

mv * .[^.]* ..

或(有关更多信息,请参见下文):

(shopt -s dotglob; mv -- * ..)

说明:该mv命令移动文件和目录。最后一个参数mv是目标(在本例中,目录在树中“向上”一步..)。之前的参数是源文件和目录。星号(*)是通配符,它​​匹配所有不以点开头的文件。以点开头的文件(点文件)被“隐藏”。它们使用模式进行匹配.[^.]*(请参见下面的编辑)。

有关的更多信息,请参见我链接的手册页mv


为什么要.[^.]*代替.*

正如克里斯·约翰森(Chris Johnsen)正确指出的那样:该模式.*也与.和相匹配..。由于您不希望(也无法)移动它们,因此最好使用一种模式,该模式匹配以点号开头的文件名(除了那两个以外)。该模式.[^.]*就是这样做的:它匹配任何以点(2)开头的文件名(1),然后是不是点(3)的字符,然后是零个或多个任意字符。

正如Paggas 指出的那样,我们还必须添加模式.??*以匹配以两个点开头的文件。有关使用的其他解决方案,请参见他的答案find

提到Arjan的答案shopt是为了避免点文件的所有这些问题。但是,以破折号开头的文件仍然存在问题。它需要三个命令。不过,我还是喜欢这个主意。我建议像这样使用它:

(shopt -s dotglob; mv -- * ..)

shopt在子shell中执行(因此不需要第二次调用shopt),并使用,--因此以破折号开头的文件不会被解释为的参数mv


7
使用.*可能会导致mv产生有关无法移动.和的警告/错误..。您可以试试看mv * .[^.]* ..
克里斯·约翰森,2009年

1
@alain:不客气,欢迎来到该网站!(如果(且仅当)这里的帖子之一充分回答了您的问题,您可以将其标记为这样。这将使张贴者获得15个额外的声誉点,并同时给您2个代表。)
Stephan202,2009年

我真的很喜欢在子
外壳中

2
*。*语法没有害处-包括..仅在与chmod和chown和“ recurse”标志(即chmod -R或chown -R)一起使用时才是有害的。在这些情况下,千万不要永远键入CHOWN *或*搭配chmod - 。CHOWN路径的顶层目录你正在寻找和使用-h(不遵循符号链接)。但是,mv ..根本不做任何事情,所以不用担心。
克里斯,

1
正确的三种模式是*.[^.]*..?*。第二个可能 .[!.]*适用于较旧的(POSIX)外壳。另请参阅

42

简短答案:使用

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

长答案:

命令

mv * .* ..

无法.*匹配.,因为可以匹配和..。但是命令

mv * .[^.]* ..

也将不起作用,因为.[^.]*将不匹配,例如..filename!相反,我要做的是

mv * .[^.] .??* ..

将匹配除.和以外的所有内容..*将匹配所有不以a开头的文件..[^.]将匹配以点号开头的所有2个字符的文件名(不包括)..,并且.??*将匹配以点号开头的至少3个字符的所有文件名。

更好的是,您可以使用

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

避免了丑陋的glob入侵mv * .[^.] .??* ..


1
另外,我也忘记了-的重要性,因此该命令对于以短划线开头的文件名可以正常使用。我已经将-包括在我的查找答案中。使用globs的更完整答案是“ mv-*。[^。]。?? * ..”。
Paggas

+1:我回来..?*发表评论,您已经处理了。
克里斯·约翰森

1
尝试播放..可能有什么问题?它只是什么都不做,什么也做不了。还有其他命令可以执行某些操作(chmod和chown),但是mv和rm根本不执行任何操作。或..
克里斯,

1
这给了mv:非法选项-t
pal4life 2014年

1
Bono,双破折号告诉mv您停止寻找任何其他命令选项。大括号是结果文件名。加号表示不要将每个结果(即每个文件名)运行exec,而是将尽可能多的结果放在单个exec中。为了完整-t..起见,告诉移动目标位置将所有这些文件移动到。
isuldor

14

为了完整起见,还可以使用以下命令让Bash shell包含隐藏文件shopt

shopt -s dotglob
mv -- * ..
shopt -u dotglob

+1。干净得多。我认为有一点改进是有必要的。查看我的答案的更新。
09年

8

mv在使用时缺少移动隐藏文件的功能*-那么为什么不使用copy呢?

cp -rf . ..

rm -rf *

无需进入复杂的点滴解决方案并使用find命令。


警告如果您在同一文件系统中移动,则在大多数情况下,您并没有真正复制文件,而是仅更新目录条目而不移动inode或文件内容。甚至见[1 ]。使用cprm相反,您实际上是在复制所有内容。
Hastur

6
rsync -a --remove-source-files . ..

rsync 是一种功能非常强大的文件复制工具,通常用于执行有效的增量远程备份和镜像。

使用以上命令,我们告诉rsync将内容复制...

该开关-a启用递归到.子目录并启用其他一些常用选项。

开关--remove-source-files告诉rsync成功复制后删除源文件,即,它使rsync的行为类似于mv命令。


1
多一点解释会很好。
ChrisF

当然,希望现在更加清楚。
mrucci

请注意,--remove-source-files这不会删除(同步)目录。
丹尼斯

好的,可接受的解决方案给我-bash: /bin/mv: Argument list too long错误。这一作品的魅力。
userlond

2

最终尝试mv .将失败,因为mv将无法取消链接当前所在的目录。您可以mv * ..在cwd中移动文件。


2
mv * .??* ../.

*获取所有非点文件。.??*得到全部。文件长度至少为三个字节,适用于所有合法字节。您可能想要留下的任何东西,rm而不是mv无论如何。

这样../.做并没有任何直接的好处,..但是当移至目录时,这是一个很好的习惯,因为如果路径有问题,它将按照您的意愿失败。例如mv xyz bletch,当你认为 bletch是一个目录,可以由具有更确定的mv xyz bletch/.


2
您可能需要添加.[^.]以获取封面文件,例如.a
克里斯·约翰森,2009年

../和../之间没有区别。这样我就不用打扰了。斜线之后。同样,对于mv和rm,包含也不有害。和..在列表中,即mv *。* / path / to / file /并没有什么可怕或错误的地方,就像rm一样。甚至-rf。什么也没做
克里斯,

2

这个最小化的命令适用于大多数现代shell:

\mv -- {,.{[^.],??}}* ..

否则提到的是一种便携式解决方案:

\mv -- * .[^.] .??* ..

特征:

  1. \防止别名意外更改mv。

  2. -防止将包含前导连字符(-xyz)的文件名解释为命令行参数。

  3. 。[^。]匹配以。开头的所有两个字符文件名。除了 ..

  4. 。?? *与所有其他文件名匹配三个或更多个字符。

天真的实现:

  1. 以下内容将跳过隐藏的UNIX文件名(以开头的文件名)。(.bashrc)。

    mv * ..
    
  2. 以下匹配项..递归地尝试将每个目录最终一直移动到当前工作目录($ PWD或pwd)的..中。 永远不要使用。

    mv .* ..
    

2

使用该模式* .[!.] .??*比使用该模式更正确,* .[^.] .??*因为前者也可以与较旧的shell(例如ksh88)一起使用:

mv -- * .[!.] .??* ..
  • -- 当文件名以开头时,可以防止出现问题 -
  • * 匹配所有以“。”开头的文件名 .
  • 没有一个.可以/应该移动的字符文件名
  • .[!.] 匹配以两个字符开头的所有两个字符文件名 .
  • .??* 匹配以三个字符开头(或更长)的所有三个字符文件名 .

使用ksh88,文件名模式.[^.]实际上将与文件名..(始终存在)和.^(可能不存在)匹配,其效果与所需的相反。


0

查找和grep也可以。如果您想通过修改find​​和egrep选择更复杂的条件来选择文件,这种结构可能会有所帮助。

find -maxdepth 1 | egrep '^./.'         # Returns all files

mv `find -maxdepth 1 | egrep '^./.'` .. # mv <all files> ..

0

我认为将所有文件移至其父目录的最简单解决方案。将会

mv "`ls`" ../

或者,如果存在隐藏的文件/目录

采用:

mv "`ls -a`" ../ 2>/dev/null

另外,假设您要将某个文件夹的内容移动到其内部文件夹之一tony(例如)

采用:

mv "`ls -a`" /tony 2>/dev/null

注意:

"`ls -a`" 

移动其中有空格的文件。

2>/dev/null

用于抑制警告/错误,因为ls -a也会打印...文件夹,并且您无法移动或复制它们。因此,对于那些文件夹,它将显示错误(如果我们不使用2> / dev / null),则无法移动它们,其余的将非常舒适地移动。

ls -a如果没有隐藏文件,最好避免使用ls


您是否尝试过跑步时会发生什么mv $(ls -a)?点击当前目录及其下的目录,因为ls -a也会输出..
萨米·莱恩2014年

谢谢@SamiLaine的建议,我已进行了更正。但是mv ls -a ../也可以根据需要工作,是的,它将显示我上面提到的那些错误,但除此之外,它会将所需的文件夹/文件移动到父目录。
Prabhat Kumar Singh

这不适用于带有空格的文件。
kenorb

@kenorb,您需要对ls命令加双引号以移动带有空格的文件。我已经进行了必要的更改。感谢您指出。
Prabhat Kumar Singh
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.