将具有特定扩展名的所有文件从多个子目录移动到一个目录


43

我在几个目录中有一堆.zip文件:

Fol1/Fol2
Fol3
Fol4/Fol5

我该如何将它们全部移到一个公共基本文件夹中?


您要保留目录结构吗?您要移动目录还是仅移动zip文件?
jordanm

我只想移动zip文件。我并不在乎目录-它们可以单独放置或删除。
InquilineKea 2013年

Answers:


55

转到包含zip文件(cd …)的树的顶级目录,然后运行

mv **/*.zip /path/to/single/target/directory

这在zsh中是开箱即用的。如果您的shell是bash,则需要首先运行shopt -s globstar(您可以并且应该将此命令放入~/.bashrc)。如果您的shell是ksh,则需要先运行set -o globstar(将其放入~/.kshrc)。

另外,可以使用use find,它无需特殊准备即可在任何地方使用,但更为复杂:

find . -name '*.zip' -exec mv {} /path/to/single/target/directory \;

如果以后要删除空目录,请在zsh中:

rmdir **/*(/^Fod)

在bash或ksh中:

rmdir **/*/

并重复此操作,直到有空目录要删除。或者,在任何外壳中

find . -depth -type d -empty -exec rmdir {} \;

find上面的第一个命令在bash中起作用,但是必须更改为find . -nameetc才能使其起作用。
JeffThompson '17

1
@Jeff .对于GNU find是隐式的,但对于其他人则不是,我已将其显式添加。
吉尔(Gilles)'所以

13

如果只想移动.zip文件,则可以执行以下操作

mkdir ./zipfiles
find . -name "*.zip" -exec mv "{}" ./zipfiles \;

3

如果您使用的是bash版本4或更高版本或zsh,则还可以使用递归glob:

mv **/*.zip /path/to/move/zip/files/to

这将仅移动文件,而不移动它们的相对路径,因此可能会发生冲突。


相对路径是什么意思?
Kunok

2

当移动数据且无错误时,这是​​安全的,无论版本如何,它都支持大多数发行版。此命令将扫描子目录,然后移动或复制到新的目标目录。

find . -name *.flac -exec mv '{}' "./flac/" ";"
  • 在包含要移动文件的子目录的主目录中运行此命令。
  • 在这里您可以更改*.flac为类似*.zip您的情况的任何内容。或者*.doc只是任何扩展名都可以。
  • 并且mv是移动文件的命令,也可以使用cp将数据复制而不是移动。
  • ./flac/是我要将所有FLAC文件移动到的目标目录。您也可以给它一个完整的路径,例如/home/myid/flac/

完整的例子。(在这种情况下,有许多子目录的音乐艺术家名称位于/home/myid/Music/,然后FLAC文件位于不同的子目录级别。由于我不需要艺术家文件夹,但希望将所有FLAC文件放在一个目录中/home/myid/Music/flac/

cd /home/myid/Music
mkdir flac
find . -name *.flac -exec mv '{}' "./flac/" ";"
cd flac
ls

然后它将显示所有FLAC文件。


怎么;办?
Francesco Boi

@FrancescoBoi,请确保等到同一行中的bash命令完成其工作。然后继续进行bash命令的下一行。这对于包含诸如.pl或python之类的脚本的命令很有用,因为bash会先运行它,然后跳转到下一行,所以为了安全起见,我使用; 在花费时间或脚本的命令之后,以防bash跳过它。
Seandex

0

作为bash hack,您可以使用以下功能tar

(cd origin/;find . -exec file --mime-type "{}" \;|grep "application/zip"|cut -d ':' -f 1|xargs tar cf -)|(cd target/; tar xf -) && rm -fr origin/

这样做的优点是它不依赖于文件扩展名,因为它使用file命令选择要移动的文件,并且保留了目录结构,但是不适用于包含空格的路径。

最后rm就是删除原始文件(因为@InquilineKea告诉他他不在乎注释中的原始文件夹)。

当然,如果原始文件夹和目标文件夹位于不同的磁盘上,则这特别适合。否则,提出的其他解决方案将更加高效(即使它们依赖于命名约定而不是file内容)。


0

假设您具有find和mv的GNU版本,则以下内容将比现有的基于find的答案更有效:

find . -name '*.zip' -exec mv --target-directory='/path/to/outputdir' '{}' +

+在find -exec末尾使用a 意味着将文件列表传递给mv命令,而不是对找到的每个文件执行一个mv命令。但是,这样做的局限性在于您只能在命令的末尾放置“ {}”,这需要使用mv --target-directory选项,据我所知,这是一种GNU主义。

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.