移动不是目录的每个文件

移动不是目录的每个文件

我有一个正在尝试清理的目录,其中包含文件和子目录。我想做的很简单:将所有文件移到另一个目录中,但保留所有子目录不变。

我在想这样的事情:

mv [*_but_no_dirs] ./other_directory

似乎应该有一种简单的方法来使用通配符*和正则表达式来做到这一点......

有人有想法吗?

答案1

这里不涉及正则表达式。 bash 中的通配符(与大多数其他 shell 一样)仅根据文件名匹配文件,而不是根据文件类型或其他特征匹配文件。有一种按类型匹配的方法:/在模式末尾添加使其仅匹配目录或目录的符号链接。通过这种方式,您可以移动目录,然后移动剩下的目录,然后将目录移回来——虽然很麻烦,但很有效。

tmp=$(TMPDIR=.. mktemp -d)
mv -- */ "$tmp"
mv -- * other_directory/
mv "$tmp"/* .
rmdir "$tmp"

(如果当前目录是文件系统的挂载点,则应该避免这种方法,因为这意味着将目录移走和移回必须将其中的所有数据复制两次)。

按类型匹配文件的标准方法是调用find

find . -name . -o -type d -prune -o -exec sh -c 'mv "$@" "$0"' other_directory/ {} +

(还移动符号链接,无论它们是否指向目录)。

在 zsh 中,您可以使用全局限定符按类型匹配文件。限定符.匹配常规文件;用于^/匹配所有非目录,或-^/也排除目录的符号链接。

mv -- *(.) other_directory/

在任何 shell 中,您都可以简单地循环。

for x in *; do
   if [ ! -d "$x" ]; then
     mv -- "$x" other_directory/
   fi
done

(不将符号链接移动到目录)。

答案2

你可以使用类似的东西

find . -maxdepth 1 \( ! -type d \) -exec sh -c 'mv  "$@" MYDIR' _ {} \;

首先,我们find只在当前目录中查找,然后我们通过使用! -type d finally来忽略目录,我们执行sh并将所有内容移动到目标目录。你可以 {} +在最后尝试一下,这样会更快。

答案3

这可能有点危险,但是

cp * destination/
rm *

因为 cp 和 rm 都无法在没有 -r 开关的目录上运行。

答案4

mv $(find /my/source/directory -maxdepth 1 -type f) /my/destination/directory

Move 将采用参数列表,因此当您要求find提供 中所有类型为“文件”的内容时/my/source/directory,它会将它们一一移动到/my/destination/directory。如果您还想将文件包含在子目录中,同时保持目录结构不变,请-maxdepth 1从上述命令中删除。

相关内容