如果当前工作目录中有多个子目录,我只想将特定文件类型或这些目录的所有内容移动到工作目录。然后;“rmdir *”那些空目录或“rm -r”那些目录(如果不为空)
这难道不应该使用“find”实用程序然后将输出通过管道传输到“mv .”(将查找结果移动到工作目录)吗?如果是这样,我需要传递哪些查找选项,或者应该使用什么样的命令来 rm 或 mv 子目录中的文件,然后可能删除目录?
这种方法是否可以安全地移动同一目录中的重复文件名?或者,如果有很多 index.html,这些文件是否会被覆盖?
这应该是 unix 中的一个基本任务,从几个子目录中 mv 或 rm 指定的文件类型
答案1
下面的操作会将所有 HTML 文件移出foo
,并删除空目录:
$ find foo -name '*.html' -type f -exec mv -nv "{}" '.' \;
foo/bar/1.html -> ./1.html
./1.html not overwritten
foo/baz/qux/3.html -> ./3.html
foo/baz/qux/5.html -> ./5.html
$ find foo -depth -type d -delete
剩下的是文件名冲突的 HTML 文件、非 HTML 文件和非空文件夹。
要自动重命名文件以防止文件名重复,可以使用mktemp
。 不同操作系统的语法不同,下面的语法适用于 OS X 和 BSD:
find foo -name '*.html' -type f -exec bash -c 'mv -v "$0" "./$( mktemp "$( basename "$0" ).XXX" )"' '{}' \;
foo/bar/1.html -> ./1.html.yNr
foo/baz/1.html -> ./1.html.RUu
foo/baz/qux/3.html -> ./3.html.rzu
foo/baz/qux/5.html -> ./5.html.JyW
对于它找到的每个 HTML 文件,它都会启动 bash 并让其执行后面的命令-c
,该命令实际上只是一个在当前目录中mv
动态创建(使用)目标文件名的命令。mktemp
为了确保它能按预期工作,您可以先使用echo
该mv
命令进行预览:
find foo -name '*.html' -type f -exec bash -c 'echo mv -v "$0" "./$( mktemp "$( basename "$0" ).XXX" )"' '{}' \;
mv -v foo/bar/1.html ./1.html.VNf
mv -v foo/baz/1.html ./1.html.pCW
mv -v foo/baz/qux/3.html ./3.html.ADN
mv -v foo/baz/qux/5.html ./5.html.K3w
如您所见,由于脚本mktemp
的原因,每次调用都会产生不同的后缀bash
(您不能只将该部分包含在常规中-exec mv
,因为它会针对调用进行一次评估find
,然后对所有移动使用相同的后缀)。
根据所涉及的文件数量,您可能需要比 更大的随机后缀.XXX
。
答案2
您可以使用以下命令一次性完成此操作:\
find . -name '*.goaway' -exec mv '{}' destination \;
但更安全的方法可能是首先查看 find 命令为您挖掘的内容,然后将其传输到可用于执行实际操作的文件中。
是的,如果您将所有 index.html 移动到同一个目录,它们会互相干扰,并且只会剩下最后一个移动的文件。