如何在 shell 中的目录中同时使用 grep 和 mv?

如何在 shell 中的目录中同时使用 grep 和 mv?

如何 grep 目录中“TEST”的所有文件的内容,然后将这些文件移动到不同的目录(例如主目录)?

答案1

您可以组合grep寻找对于此任务:

find SOURCE -maxdepth 1 -type f -exec grep -q TEST {} \; -exec mv -i {} DEST \;

怎么运行的

  • find SOURCE -maxdepth 1 -type f-type f查找目录中的所有文件 ( )来源

    如果您还想包含子目录中的文件,只需删除-maxdepth 1

  • -exec grep -q TEST {} \;逐个搜索文件,查找字符串测试。这里,{}是当前正在处理的文件。

    -q开关使 grep “安静”,即它不会输出任何内容。-exec如果grep成功,即找到了字符串。

  • -exec mv -i {} DEST \;移动包含字符串的文件测试进入目录目的地

    开关-i制造动量“交互式”,即在覆盖其他文件之前会进行提示。

答案2

只是另一种选择(但这需要一些 GNU 特定的扩展;因为您将问题标记为“Unix”,所以它可能不适合您):

grep -lZd skip TEST SOURCE/* | xargs -0I{} mv -i {} DEST
  • grep -l

    打印匹配的文件名而不是正常输出。

  • grep -Z

    给出空字节分隔的输出,这是处理管道上奇怪的文件名的安全选择。

  • grep -d skip

    定义skip输入参数中遇到的目录的操作。

    这其实不是必需的;它只是避免在遇到目录时发出通知grep: SOURCE/DIR: Is a directory。如果您想要递归读取目录中的文件,请使用操作recurse,或者更短的等效-r开关(另请参阅下面的要点)。

  • SOURCE/*

    SOURCE使用 shell匹配目录中的所有文件通配符。隐藏文件默认不匹配;可以在发出命令shopt -s dotglob之前通过 Bash 中的设置来更改此设置。grep

    人们可能会倾向于只添加SOURCE/.*输入参数,但如果使用,这可能会产生意想不到的后果-r(因为我们匹配.并且..)。

    如果需要递归匹配,只需使用-r SOURCE不带文件通配符作为输入参数,其中包括目录结构中的隐藏文件。

  • xargs -0

    将输入解释为空分隔。

  • xargs -I{}

    定义{}为输入参数的占位符。

  • mv -i

    按照丹尼斯的建议使这一举动具有互动性,以避免错误。

为了测试此模式(或一般命令),一个有用的技巧是echo在实际命令前插入以查看要执行哪些命令,即更改mvecho mv

答案3

$ mv TEST* /路径/到/目的地

对我来说有效,希望对你也有用。就我而言,它是:

$ mv note_[5,6]* ~/documents/notes

将 note_5_math.pdf 和 note_6_math.pdf 移至 home/documents/notes 目录。

相关内容