我有一个正在尝试清理的目录,其中包含文件和子目录。我想做的很简单:将所有文件移到另一个目录中,但保留所有子目录不变。
我在想这样的事情:
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
从上述命令中删除。