it-swarm.cn

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

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

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

mv Foo/* Bar/

自己尝试。

mkdir Foo
mkdir Bar
touch Foo/.hidden
touch Foo/notHidden
mv Foo/* Bar/
155
Cory Klein

Sh

mv Foo/*(DN) Bar/

要么

setopt -s glob_dots
mv Foo/*(N) Bar/

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

Bash

shopt -s dotglob nullglob
mv Foo/* Bar/

93号

如果您知道目录不为空:

FIGNORE='.?(.)'
mv Foo/* Bar/

标准(POSIX)sh

for x in Foo/* Foo/.[!.]* Foo/..?*; do
  if [ -e "$x" ]; then mv -- "$x" Bar/; fi
done

如果您愿意让mv命令返回错误状态,即使该命令成功执行,也要简单得多:

mv Foo/* Foo/.[!.]* Foo/..?* Bar/

GNU查找和GNU mv

find Foo/ -mindepth 1 -maxdepth 1 -exec mv -t Bar/ -- {} +

标准查找

如果您不介意切换到源目录:

cd Foo/ &&
find . -name . -o -exec sh -c 'mv -- "[email protected]" "$0"' ../Bar/ {} + -type d -Prune

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

Bash

设置 dotglob选项

$ echo *
none zero
$ shopt -s dotglob
$ echo *
..two .one none zero

还有一个更灵活的 GLOBIGNORE变量 ,您可以将其设置为以冒号分隔的通配符模式列表,以将其忽略。如果未设置(默认设置),则如果设置dotglob,则Shell的行为就好像该值为空,如果未设置该选项,则该行为就好像是.*。请参见手册中的 文件名扩展 。始终会忽略普遍使用的目录...,除非.与该模式明确匹配。

$ GLOBIGNORE='n*'
$ echo *
..two .one zero
$ echo .*
..two .one
$ unset GLOBIGNORE
$ echo .*
. .. ..two .one
$ GLOBIGNORE=.:..
$ echo .*
..two .one

93号

设置 FIGNORE变量 。如果未设置(默认设置),则命令行管理程序的行为就像该值是.*。要忽略...,必须将它们显式匹配(ksh 93s + 2008-01-31中的手册指出,始终会忽略...,但这不能正确描述实际行为)。

$ echo *
none zero
$ FIGNORE='@(.|..)'
$ echo *
..two .one none zero
$ FIGNORE='n*'
$ echo *
. .. ..two .one zero

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

$ unset FIGNORE
$ echo @(*|.[^.]*|..?*)
..two .one none zero

要使扩展名在目录为空的情况下为空,请使用N模式匹配选项:~(N)@(*|.[^.]*|..?*)~(N:*|.[^.]*|..?*)

Sh

设置 dot_glob选项

% echo *
none zero
% setopt dot_glob
% echo *
..two .one none zero

...永远不会匹配,即使该模式显式匹配前导.

% echo .*
..two .one

您可以使用D(glob qualifier )以特定模式包含点文件。

% echo *(D)
..two .one none zero

添加N glob限定符,以使扩展在空目录_*(DN)中为空。


注意:根据.one..twonone变量的设置,您可以按不同顺序获得文件名扩展结果(例如LANG,后跟LC_COLLATE,然后是LC_ALL)。

178
#!/bin/bash

shopt -s dotglob
mv Foo/* Bar/

来自man bash

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

24
SiegeX

bash中执行此操作的一种简单方法是

_mv {Foo/*,Foo/.*} Bar/
_

但这也会移动目录。

如果要移动所有文件(包括隐藏文件),但又不想移动任何目录,则可以使用for循环和测试。

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

11
Boris Month

一种方法是使用find

find Foo/ -type f -exec mv -t Bar/ {} \+

-type f将find命令限制为查找文件。您应该研究find-type-maxdepth-mindepth选项,以自定义命令以说明子目录。查找具有冗长但非常有用的 手册页

4
Steven D

尝试复制命令cp

$ cp -r myfolder/* destinationfolder

cp -r表示递归复制,因此将复制所有文件夹和文件。

您可以使用删除命令rm删除文件夹:

$ rm -r myfolder

查看更多: 将所有文件从目录移动到另一个目录

2
ucefkh

对于minimumLinux发行版,以下应该起作用。首先,执行全部基本移动(丢失所有隐藏文件)。然后,移动所有隐藏文件(包括...,将not实际移动)。

mv /sourceDir/* /destinationDir 2> /dev/null
mv /sourceDir/.* /destinationDir 2> /dev/null

注意:如果没有可见的内容,第一个命令将产生一条错误消息。第二个命令将总是产生一个错误,指出它不能移动...。因此,只需将错误输入/dev/null (如图所示)。

如果您需要将此作为单线,只需将它们与分号结合使用:

mv /sourceDir/* /destinationDir 2> /dev/null; mv /sourceDir/.* /destinationDir 2> /dev/null
1
BuvinJ

Rsync是另一种选择:

rsync -axvP --remove-source-files sourcedirectory/ targetdirectory

之所以有效,是因为在rsync中尾随斜杠很重要,sourcedirectory/指目录的内容,而sourcedirectory指目录本身。

此方法的缺点是rsync仅在移动后清除文件,而不清除目录。因此,您将剩下一个空的源目录树。有关解决方法,请参见:

使用rsync移动文件并删除目录吗?

因此,尽管这对于移动操作可能不是最佳选择,但对于复制操作可能非常有用。

1
Grumbel

bash /鱼的答案

这是使用通配符的一种方法:

.[!.]* ..?*将匹配所有隐藏文件,但...

.[!.]* ..?* *将匹配所有文件(是否隐藏),但...

要回答此问题的特定示例,您需要cd foo && mv .[!.]* ..?* * ../bar

说明

.[!.]*匹配以一个点开头的文件名,然后是除点以外的任何字符(可选),然后是任何字符串。这足够接近,但是会丢失以两个点开头的文件,例如..foo。为了包括这些文件,我们添加..?*匹配以两个点开头的文件名,后跟任意字符,可选,后跟任意字符串。

测试

您可以使用以下命令测试这些通配符。我已经成功地在bash和fish下尝试了它们。他们在sh,zsh,xonsh下失败。

mkdir temp
cd temp
touch  a  .b  .bc  ..c  ..cd  ...d  ...de
ls .[!.]* ..?*
# you get this output:
          .b  .bc  ..c  ..cd  ...d  ...de
# cleanup
cd ..
rm -rf temp
1
ndemou

我发现这对bash效果很好,不需要更改Shell选项

mv sourcedir/{*,.[^.]*} destdir/

编辑:

因此,正如G-man所言,我的原始答案不符合posix,并且与ndemou的答案几乎相同,只是作了一次更改,即使用括号扩展来创建字符串列表,然后对其进行操作。这只是意味着您不需要cd进入源目录。确实变化不大,但是却有所不同。

示例:假设您已经具有以下布局。

 $ tree -a
.
├── destdir
└── sourcedir
    ├── ..d1
    ├── ..d2
    ├── ..double
    ├── file-1
    ├── file-2
    ├── .hidden-1
    ├── .hidden-2
    ├── ...t1
    └── ...t2

最初的问题只提到了带有单个句点的隐藏文件,但让我们说一些在文件名开头带有两个或多个句点的文件。您可以在括号中添加一个附加表达式。然后我们可以执行

mv sourcedir/{*,.[!.]*,..?*} destdir/

这被扩展为以下内容:

mv sourcedir/file-1 sourcedir/file-2 sourcedir/.hidden-1 sourcedir/.hidden-2 sourcedir/..d1 sourcedir/..d2 sourcedir/..double sourcedir/...t1 sourcedir/...t2 destdir/

现在您应该看到位于destdir中的所有文件:

 $ tree -a
.
├── destdir
│   ├── ..d1
│   ├── ..d2
│   ├── ..double
│   ├── file-1
│   ├── file-2
│   ├── .hidden-1
│   ├── .hidden-2
│   ├── ...t1
│   └── ...t2
└── sourcedir

您可以使用bash中的花括号来做一些非常酷的事情,在4.x中甚至可以添加更多内容。查看 bash-hackers 以获得一些漂亮的示例。

0
cmndr sp0ck

您也许还可以找到带有反引号的grep并进行grep选择,以选择move命令的文件。将它们传递到mv。

即对于隐藏文件

find Foo -maxdepth 1 | egrep '^Foo/[.]' # Output: .hidden

所以

mv `find Foo -maxdepth 1 | egrep '^Foo/[.]'` Bar # mv Foo/.hidden Bar

仅将选定的隐藏文件移动到Bar

mv `find Foo -maxdepth 1 | egrep '^Foo/.'` Bar # mv Foo/.hidden Foo/notHidden Bar

从“。”开始将Foo中的所有文件移动到Bar。 egrep命令中的命令用作通配符,不带方括号。

^字符可确保匹配从行的开头开始。

egrep模式匹配的一些详细信息可以在 此处 中找到。

使用maxdepth 1停止查找子目录。

0
user3192145

灵感来自 此答案

无需复制文件...

rsync -ax --link-dest=../Foo/ Foo/ Bar

注意事项:

  • --link-dest路径必须是绝对路径或相对于DESTINATION路径(在示例中为Bar

  • 您必须输入/在SOURCE之后(Foo/),否则它将复制SOURCE文件夹而不是其内容。

0
palindrom