代码之家  ›  专栏  ›  技术社区  ›  HaveAGuess

如何突出显示文件中后续行之间的差异?

  •  3
  • HaveAGuess  · 技术社区  · 15 年前

    我做了很多紧急分析大日志文件分析。这通常需要跟踪日志并查找更改。

    我已经调查了工具,似乎没有什么东西可以做我要找的。我已经用Perl编写了一些脚本,可以大致完成这项工作,但我希望有一个更完整的解决方案。

    有人能推荐一个工具吗?

    3 回复  |  直到 14 年前
        1
  •  1
  •   arekolek    10 年前

    我为此编写了一个Python脚本 difflib.SequenceMatcher :

    #!/usr/bin/python3
    
    from difflib import SequenceMatcher
    from itertools import tee
    from sys import stdin
    
    def pairwise(iterable):
        """s -> (s0,s1), (s1,s2), (s2, s3), ...
    
        https://docs.python.org/3/library/itertools.html#itertools-recipes
        """
        a, b = tee(iterable)
        next(b, None)
        return zip(a, b)
    
    def color(c, s):
      """Wrap string s in color c.
    
      Based on http://stackoverflow.com/a/287944/1916449
      """
      try:
        lookup = {'r':'\033[91m', 'g':'\033[92m', 'b':'\033[1m'}
        return lookup[c] + str(s) + '\033[0m'
      except KeyError:
        return s
    
    def diff(a, b):
      """Returns a list of paired and colored differences between a and b."""
      for tag, i, j, k, l in SequenceMatcher(None, a, b).get_opcodes():
        if tag == 'equal': yield 2 * [color('w', a[i:j])]
        if tag in ('delete', 'replace'): yield color('r', a[i:j]), ''
        if tag in ('insert', 'replace'): yield '', color('g', b[k:l])
    
    if __name__ == '__main__':
      for a, b in pairwise(stdin):
        print(*map(''.join, zip(*diff(a, b))), sep='')
    

    例子 input.txt :

    108  finished   /tmp/ts-out.5KS8bq   0       435.63/429.00/6.29 ./eval.exe -z 30
    107  finished   /tmp/ts-out.z0tKmX   0       456.10/448.36/7.26 ./eval.exe -z 30
    110  finished   /tmp/ts-out.wrYCrk   0       0.00/0.00/0.00 tail -n 1
    111  finished   /tmp/ts-out.HALY18   0       460.65/456.02/4.47 ./eval.exe -z 30
    112  finished   /tmp/ts-out.6hdkH5   0       292.26/272.98/19.12 ./eval.exe -z 1000
    113  finished   /tmp/ts-out.eFBgoG   0       837.49/825.82/11.34 ./eval.exe -z 10
    

    cat input.txt | ./linediff.py :

    linediff output

        2
  •  3
  •   Margus    15 年前

    Levenshtein距离

    维基百科: 两个字符串之间的Levenshtein距离是将一个字符串转换为另一个字符串所需的最小操作数,其中一个操作是插入、删除或替换单个字符。

    public static int LevenshteinDistance(char[] s1, char[] s2) {
        int s1p = s1.length, s2p = s2.length;
        int[][] num = new int[s1p + 1][s2p + 1];
    
        // fill arrays
        for (int i = 0; i <= s1p; i++)
            num[i][0] = i;
    
        for (int i = 0; i <= s2p; i++)
            num[0][i] = i;
    
        for (int i = 1; i <= s1p; i++)
            for (int j = 1; j <= s2p; j++)
                num[i][j] = Math.min(Math.min(num[i - 1][j] + 1,
                        num[i][j - 1] + 1), num[i - 1][j - 1]
                        + (s1[i - 1] == s2[j - 1] ? 0 : 1));
    
        return num[s1p][s2p];
    }
    

    Java中的示例应用程序

    字符串差异

    alt text

    应用程序使用LCS算法将2个文本输入串联成1个文本输入。结果将包含使一个字符串成为另一个字符串的最小指令集。下面将显示指令串联文本。

    String Diff.jar

    下载源: Diff.java

    推荐文章