移动所有不以 .txt 结尾的文件

移动所有不以 .txt 结尾的文件

在目录中/home/username/data我既有文件又有目录。其中一些文件名以.txt(我将其称为文本文件),其他人则没有。子目录中也会发生同样的情况。

调用其中一个子目录other_files(其完整路径为/home/username/data/other_files/)。

我想移动所有不以.txt 在根中 /home/username/dataother_files


我可以用循环来做到这一点,但这不是我想要的。我想使用命令和管道。我相信这很容易,只是我没有看到。mvfindgrep和的组合xargs应该可以做到这一点,我只是不确定如何做。

所以我一直在尝试匹配文本文件(然后想办法匹配除它们之外的所有内容)。下面假设我当前的目录是/home/username/data.
首先我选择了find . | grep -E "*\.txt",但这匹配所有文本文件,包括子目录中的文件。
所以我试着find . | grep -E "\./*\.txt"看看我是否会得到相同的比赛,然后朝着我的目标努力,但这与任何东西都不匹配,这就是我陷入困境的地方。


我该如何去做我在问题开头所描述的事情?

答案1

简单的 shell 循环变体(在bash):

shopt -s extglob dotglob nullglob

for pathname in ~username/data/!(*.txt); do
    ! test -d "$pathname" && mv "$pathname" ~username/data/other_files
done

第一行设置的 shell 选项将使bashshell 启用扩展的通配模式(!(*.txt)以匹配所有不以 结尾的名称.txt),它使通配模式能够匹配隐藏名称,并且如果没有任何匹配,它会使模式扩展为空。

循环体将跳过目录(或目录的符号链接)中的任何内容,并将其他所有内容移动到给定目录。

find与GNU等效的东西mv(如果有的话,会将符号链接移动到目录,并且mv一次会调用尽可能多的文件,但这些是唯一的区别):

find ~username/data -maxdepth 1 ! -type d ! -name '*.txt' \
    -exec mv -t ~username/data/other_files {} +

有关的:

答案2

find /home/username/data -maxdepth 1 -type f ! -name '*.txt' -exec mv {} /home/username/data/other_files/ \;
  • 最高层董事的最大深度限制
  • type 确保只找到文件,而不找到目录

答案3

此代码应将所有不以“.txt”结尾的文件移动到目标文件夹,但是如果您碰巧在不同路径中具有相同名称的文件,则会引发错误。

find /home/username/data ! -name "*.txt" -type f -maxdepth 1 -exec mv {} /home/username/data/other_files/ \;

答案4

以下行查找当前目录中所有不是*.txt且不是路径的文件和隐藏文件,并将它们移动到新路径中:

ls -1p | grep -v "^.*\.txt$" | grep -v ".*/$" | xargs mv -vt newpath

以下内容相同,但也移动隐藏文件:

ls -1ap | grep -v "^.*\.txt$" | grep -v ".*/$" | xargs mv -vt newpath

两个命令行都不递归扫描目录,也不移动目录

如果您的文件名包含空格,您可以使用:

ls -1ap | grep -v "^.*\.txt$" | grep -v ".*/$" | xargs -d'\n' printf "\"%s\"\n" | xargs mv -vt newpath

相关内容