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

我尝试了类似mv *.*的操作,但它不起作用。

评论

我没有足够的代表来重新标记问题,但是我可以建议[linux] [mv] [cwd] [files]或类似的东西吗?

我已按照Stephan202的要求重新标记了这个问题。

unix.stackexchange.com/a/251091/139312

#1 楼

您要查找的命令是

mv * .[^.]* ..


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

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


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

有关mv的更多信息,请参见我链接的联机帮助页。


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

Paggas指出,我们还必须添加模式.??*,以匹配以两个点开头的文件。请参阅他的答案以获取使用find的替代解决方案。

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

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


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

评论


使用。*可能会导致mv产生有关无法移动的警告/错误。并且...您可以尝试使用mv *。[^。] * ..代替。

–克里斯·约翰森(Chris Johnsen)
09-10-28在19:21

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

– Stephan202
09-10-28在19:41

我真的很喜欢在subshel​​l中运行的shopt解决方案:)

– Paggas
09-10-29在20:04

*。*语法没有任何危害-包括..仅在与chmod和chown和“ recurse”标志(即chmod -R或chown -R)一起使用时才是有害的。在那种情况下,永远不要键入chown。*或chmod。* - chown您要查找的路径中的顶层目录,并使用-h(不要遵循符号链接)。但是,mv ..根本不做任何事情,所以不用担心。

–克里斯
09年11月6日在4:16

正确的三个模式是* 、. [^。] *和..?*。对于较旧的(POSIX)外壳,第二个可能是。[!。] *。也看了

–user353322
16年5月1日在7:06

#2 楼

简短答案:使用

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


长答案:

命令

mv * .* ..


将不起作用,因为.*可以匹配...。但是命令

mv * .[^.]* ..


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

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


,它将匹配除...之外的所有内容。 *将匹配所有不以.开头的文件,.[^.]匹配所有以2个字符开头的文件名,除了..以外,.??*匹配所有以至少3个字符开头的文件名。

更好的是,您可以使用

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


,从而避免了mv * .[^.] .??* ..中难看的glob骇客!

评论


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

– Paggas
09-10-28在20:45

+1:我回来添加..?*至我的评论,您已经照顾好了。

–克里斯·约翰森(Chris Johnsen)
09-10-29在3:10

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

–克里斯
09年11月6日在4:18

这给出了mv:非法选项-t

–pal4life
14年7月29日在21:08

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

– isuldor
18年1月2日在1:00



#3 楼

为了完整起见,还可以使用shopt告诉Bash shell包括隐藏文件:

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


评论


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

– Stephan202
09-10-28在21:11

#4 楼

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

cp -rf . ..

rm -rf *


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

评论


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

–Hastur
16年1月22日在10:22



#5 楼

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


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

通过上述命令,我们告诉rsync复制内容将.插入..

开关-a启用递归到.子目录并启用一些其他常用选项。也就是说,它使rsync的行为类似于--remove-source-files命令。

评论


多一点解释会很好。

– ChristF
13年1月20日在12:20

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

–mrucci
13年1月20日在16:25

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

–丹尼斯
13-10-25在18:22

不错,可以接受的解决方案给我-bash:/ bin / mv:参数列表过长的错误。这一作品就像魅力。

–用户
16年11月28日在6:09

#6 楼

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

#7 楼

mv * .??* ../.


*获取所有非点文件。 .??*获得全部。文件长度至少为三个字节,适用于所有合法字节。无论如何,您可能只想使用rm而不是mv。因为如果路径有问题,它将按照您的意愿失败。例如,可以使用../.使..(您认为mv xyz bletch是目录)更加确定。

评论


您可以添加。[^。]以获取.a等封面文件。

–克里斯·约翰森(Chris Johnsen)
09-10-29在3:12

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

–克里斯
09年11月6日在4:21

#8 楼

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

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


否则,提到的是可移植的解决方案:

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


功能:


\防止别名不必要地更改mv。
-防止包含前导连字符(-xyz)的文件名被解释为命令行参数。
。[^。]匹配以。开头的所有两个字符文件名。除了..
。?? *匹配所有其他文件名三个或三个以上字符。

朴素的实现:




以下跳过隐藏的UNIX文件名,以开头的文件名。 (.bashrc)。

mv * ..



以下匹配..递归地尝试将每个目录最终一路移回/移至..当前工作目录($ PWD或pwd)。切勿使用。

mv .* ..




#9 楼

使用模式* .[!.] .??*比使用* .[^.] .??*更正确,因为前者也可以用于较旧的外壳,例如ksh88:

mv -- * .[!.] .??* ..





--可以防止当您具有以-开头的文件名时出现问题


*匹配所有不以.开头的文件名

没有一个字符文件以/可以移动的.开头的名称

.[!.]匹配以.开头的所有两个字符文件名


.??*匹配所有三个字符文件的以.开头的名称(或更长的名称)


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

#10 楼

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

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

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


#11 楼

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

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也将输出..。

–user260419
2014年8月6日在16:46



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

– Prathat Kumar Singh
2014年8月8日上午10:45

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

– Kenorb
15年5月27日在22:47

@kenorb,您需要双引号ls命令以移动带有空格的文件。我已经进行了必要的更改。感谢您指出。

– Prathat Kumar Singh
18年4月4日在9:48