如何将所有文件(包括隐藏文件)从一个目录移动到另一个目录?

Cor*_*ein 192 shell wildcards dot-files mv

如何将目录中的所有文件(包括隐藏文件)移动到另一个目录?

例如,如果我有一个文件夹“Foo”,里面有文件“.hidden”和“notHidden”,我如何将这两个文件移动到名为“Bar”的目录中?以下不起作用,因为“.hidden”文件保留在“Foo”中。

mv Foo/* Bar/
Run Code Online (Sandbox Code Playgroud)

自己试试吧。

mkdir Foo
mkdir Bar
touch Foo/.hidden
touch Foo/notHidden
mv Foo/* Bar/
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 223

Zsh

mv Foo/*(DN) Bar/
Run Code Online (Sandbox Code Playgroud)

或者

setopt -s glob_dots
mv Foo/*(N) Bar/
Run Code Online (Sandbox Code Playgroud)

(N)如果您知道目录不为空,则省略。)

重击

shopt -s dotglob nullglob
mv Foo/* Bar/
Run Code Online (Sandbox Code Playgroud)

Ksh93

如果您知道目录不为空:

FIGNORE='.?(.)'
mv Foo/* Bar/
Run Code Online (Sandbox Code Playgroud)

标准 (POSIX) sh

for x in Foo/* Foo/.[!.]* Foo/..?*; do
  if [ -e "$x" ]; then mv -- "$x" Bar/; fi
done
Run Code Online (Sandbox Code Playgroud)

如果您愿意让mv命令即使成功也返回错误状态,那就简单多了:

mv Foo/* Foo/.[!.]* Foo/..?* Bar/
Run Code Online (Sandbox Code Playgroud)

GNU 查找和 GNU mv

find Foo/ -mindepth 1 -maxdepth 1 -exec mv -t Bar/ -- {} +
Run Code Online (Sandbox Code Playgroud)

标准查找

如果您不介意更改到源目录:

cd Foo/ &&
find . -name . -o -exec sh -c 'mv -- "$@" "$0"' ../Bar/ {} + -type d -prune
Run Code Online (Sandbox Code Playgroud)

这里有更多关于控制点文件是否在 bash、ksh93 和 zsh 中匹配的详细信息。

重击

设置dotglob选项

$ echo *
none zero
$ shopt -s dotglob
$ echo *
..two .one none zero
Run Code Online (Sandbox Code Playgroud)

还有更灵活的GLOBIGNORE变量,您可以将其设置为以冒号分隔的通配符模式列表以忽略。如果未设置(默认设置),如果设置了该值,则 shell 的行为就像该值是空的dotglob一样,.*如果该选项未设置,则该值就像该值是空的一样。请参阅手册中的文件名扩展。普遍存在的目录...总是被省略,除非.由模式明确匹配。

$ GLOBIGNORE='n*'
$ echo *
..two .one zero
$ echo .*
..two .one
$ unset GLOBIGNORE
$ echo .*
. .. ..two .one
$ GLOBIGNORE=.:..
$ echo .*
..two .one
Run Code Online (Sandbox Code Playgroud)

Ksh93

设置FIGNORE变量。如果未设置(默认设置),shell 的行为就像值是.*. 要忽略.and ..,它们必须明确匹配(ksh 93s+ 2008-01-31 中的手册指出...总是被忽略,但这并没有正确描述实际行为)。

$ echo *
none zero
$ FIGNORE='@(.|..)'
$ echo *
..two .one none zero
$ FIGNORE='n*'
$ echo *
. .. ..two .one zero
Run Code Online (Sandbox Code Playgroud)

您可以通过显式匹配将点文件包含在模式中

$ unset FIGNORE
$ echo @(*|.[^.]*|..?*)
..two .one none zero
Run Code Online (Sandbox Code Playgroud)

如果目录为空,要使扩展为空,请使用N模式匹配选项:~(N)@(*|.[^.]*|..?*)~(N:*|.[^.]*|..?*)

Zsh

设置dot_glob选项

% echo *
none zero
% setopt dot_glob
% echo *
..two .one none zero
Run Code Online (Sandbox Code Playgroud)

.并且..永远不会匹配,即使模式.明确匹配前导也是如此。

% echo .*
..two .one
Run Code Online (Sandbox Code Playgroud)

您可以使用D glob 限定符以特定模式包含点文件。

% echo *(D)
..two .one none zero
Run Code Online (Sandbox Code Playgroud)

添加Nglob 限定符以使扩展在空目录中显示为空:*(DN).


注意:您可能会在不同的顺序文件名扩展的结果(例如,none后面.one接着..two根据您的设置)LC_COLLATELC_ALL以及LANG变量。

  • 为什么是“nullglob”?中止 `mv` 命令(如 Fish、csh/tcsh、zsh(不带 `(N)`),或者使用 failglob 的 bash)比运行 `mv /Bar/` 命令更有意义,后者没有什么意义。 (2认同)

Sie*_*geX 29

#!/bin/bash

shopt -s dotglob
mv Foo/* Bar/
Run Code Online (Sandbox Code Playgroud)

man bash

dotglob如果设置,bash 将包含以 '.' 开头的文件名 在路径名扩展的结果中。


Bor*_*nth 16

一个简单的方法bash

mv {Foo/*,Foo/.*} Bar/
Run Code Online (Sandbox Code Playgroud)

但这也会移动目录。

如果您想移动包括隐藏在内的所有文件但不想移动任何目录,您可以使用 for 循环和测试。

for i in $(ls -d {Foo/*,Foo/.*});do test -f $i && mv -v $i Bar/; done;