【问题标题】:Only include files that match a given pattern in a recursive diff仅在递归差异中包含与给定模式匹配的文件
【发布时间】:2012-04-25 06:58:59
【问题描述】:

如何对两个目录(a 和 b)中的文件进行递归比较:

$ diff -r a b

但只查看名称与给定模式匹配的文件。例如,使用 find 命令中可用的相同语法,如下所示:

$ diff -r a b -name "*crazy*"

这将显示 a 和 b 中具有相同名称和路径的文件之间的差异,它们的名称中有“疯狂”。

实际上,我正在寻找与 diff 中可用的 --exclude 选项相反的选项。

【问题讨论】:

  • 我同意这很有用。 grep 有一个 --include 标志

标签: shell unix diff


【解决方案1】:

我无法让它与-X - 一起工作,所以我使用了不同的方法 - 让find 根据我的要求递归查找文件,让diff 比较单个文件:

a="/your/dir"
b="/your/other/dir"
for f in $(find $a -name "*crazy*" | grep -oP "^$a/\K.*"); do
  diff -u $a/$f $b/$f
done

或者,在一行中:

a="/your/dir" && b="/your/other/dir" && for f in $(find $a -name "*crazy*" | grep -oP "^$a/\K.*"); do diff -u $a/$f $b/$f; done

grep -oP "^$a/\K.*" 用于提取相对于目录a 的路径,即它从/your/dir/and/a/file 中删除/your/dir/,使其成为and/a/file

【讨论】:

    【解决方案2】:

    也许这有点间接,但它应该有效。您可以使用find 获取 匹配模式的文件列表,然后“排除”所有这些文件:

    find a b -type f ! -name 'crazy' -printf '%f\n' | diff -r a b -X -
    

    -X - 将使diff 从标准输入读取模式并排除任何匹配的内容。如果您的文件的名称中没有像 *? 这样的有趣字符,这应该可以工作。唯一的缺点是您的 diff 不会包含 find 命令,因此列出的 diff 命令没有那么有用。

    (我只用 GNU finddiff 对其进行了测试)。

    编辑

    由于只有非 GNU 的 find 没有 -printf,所以可以使用 sed 作为替代:

    find a b -type f ! -name '*crazy*' -print | sed -e 's|.*/||' | diff -X - -r a b
    

    这也是假设非 GNU 的 diff-X,我不知道。

    【讨论】:

    • 不幸的是,这必须在 Mac OS X 上工作,我从stackoverflow.com/questions/752818/… 看到 BSD 的 find 没有 -printf 选项。因此,制作 BSD 和 GNU 兼容的命令显然不是好办法。
    • @EdwardD'Souza 如果您想在 OSX 上获得 GNU 工具,请考虑 MacPorts
    • 感谢@FatalError;您能否编辑命令的第一部分,使其仅传入“a”和“b”中的文件,而不是当前目录中的所有文件?比如:( (cd a && find . -type f ! -name *crazy* -print) && (cd b && find . -type f ! -name *crazy* -print) )
    • @EdwardD'Souza 当然可以。我用我认为应该工作的东西更新了它(我再次只熟悉这些工具的 GNU 风格)。如果这不起作用,我会根据您的建议进行更新。
    • @FatalError 我不清楚“你的差异不会包含 find 命令”是什么意思。您是说名称为“find”的文件将被排除,因为“find”一词通过管道传输到-X?我说的对吗?
    猜你喜欢
    • 2017-10-27
    • 1970-01-01
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 2019-05-07
    • 1970-01-01
    • 2018-02-11
    相关资源
    最近更新 更多