我有 50 个文件夹,还有一些子文件夹,总共有 1000 多个音频文件。我需要删除所有子文件夹并将所有文件放入当前级别。尝试过mv */* ./
,但它抱怨:参数列表太长
答案1
我假设您的音频文件扩展名是 .mp3
find <AudioFolderPath> -name '*.mp3' -exec mv -it <YourTargetFolder> {} +
笔记:
替换
.mp3
为您的音频文件扩展名替换
<AudioParentFolderPath>
为包含子文件夹的父文件夹。替换
<YourTargetFolder>
为您需要放置所有文件的文件夹路径。如果不同子文件夹中的两个文件具有相同的名称只有一个会被移动。
编辑 :作为科斯塔斯说:“-i
开关是mv
交互式的,在覆盖现有文件之前会提示”
答案2
find . -type f -mindepth 2 -exec mv -t ./ {} +
请注意,该命令将覆盖任何同名的文件。您可以使用它在覆盖之前进行提示:
find . -type f -mindepth 2 -exec mv -it ./ {} +
解释
-type f
: 只查找常规文件。-mindepth 2
:仅查找子目录中的文件。-exec mv -it ./ {}
:-exec
意思是“运行这个命令在找到的每个文件上”。将{}
被替换为文件名。-i
开关进行mv
交互,在覆盖现有文件之前会提示并将-t
目标目录设置为./
.+
:将文件放在一起(在一个参数行中),数量与 shell 可以操作的数量相同命令援引命令最少次数(不是一对一,而是一对多)。
关于进一步的空文件夹删除,您可以使用相同的接收方式:
find . -type d -empty -delete
答案3
execve()
是的,这是执行外部命令时传递给系统调用的参数和环境的累积大小的限制。
对于zsh
,您可以使用它的内置函数mv
来代替:
zmodload -F zsh/files +b:zf_mv
zf_mv ./*/* .
或者使用zargs
将列表分成可管理的块:
autoload zargs
zargs -Ifiles ./*/* -- mv files .
和ksh93
:
command -x mv ./*/* .
对于 GNUxargs
和mv
带有内置 shell 的GNU printf
(大多数mksh
是值得注意的例外):
printf '%s\0' ./*/* | xargs -r0 mv -t .
答案4
一个相当便携的解决方案可能是:
查找每个子文件夹中的所有文件,并将它们移动到当前目录中
find ./*/ -type f -print | xargs mv -i "{}" ./
您可以| egrep "\.au$|\.mp3$|\.ac3$"
在中间添加一个,以确保您找到的文件是带有音频扩展名的文件(根据需要添加尽可能多的扩展名以涵盖所有类型,我只提供 3 个常见的)