2010-10-01 6 views
2

Je fais beaucoup d'analyse urgente de l'analyse de fichiers journaux volumineux. Souvent, cela nécessitera la saisie d'un journal et la recherche de changements. Je souhaite avoir une solution qui mettra en évidence ces changements afin de faciliter le suivi de l'oeil.Comment mettre en évidence les différences entre les lignes suivantes dans un fichier?

J'ai étudié des outils et il ne semble y avoir rien là-bas qui fait ce que je cherche. J'ai écrit quelques scripts en Perl qui le font à peu près, mais je voudrais une solution plus complète.

Quelqu'un peut-il recommander un outil pour cela?

Répondre

1

I a écrit un script Python à cette fin qui utilise 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='') 

Exemple 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 

Sortie de cat input.txt | ./linediff.py:

linediff output

3

Levenshtein

Wikipedia: distance de Levenshtein entre deux chaînes est le nombre minimum d'opérations nécessaires pour transformer une chaîne dans l'autre, où une opération est une insertion, la suppression ou la substitution d'un seul caractère.

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]; 
} 

App Sample en Java

Chaîne Diff

alt text

application utilise l'algorithme LCS pour concaténer 2 entrées de texte en 1. Résultat contiendra ensemble minimal d'instructions pour faire une chaîne pour L'autre. Sous l'instruction, le texte concaténé est affiché.

Télécharger l'application: String Diff.jar

Télécharger la source: Diff.java

+0

Merci Magnus, ressemble à un bon algo savoir sur/ajouter à la liste. Pourrait m'aider à rouler mon propre mise en évidence de diff, mais idéalement, je voudrais trouver une bibliothèque/outil tel que celui dans ma réponse – HaveAGuess

+0

Linux a une commande 'diff' puissante, je voudrais regarder dans cela. – Margus

+0

Merci, je suis un utilisateur averti de cela et d'autres outils de diff. J'ai mis à jour le libellé de la question pour donner plus d'arrière-plan .. – HaveAGuess

Questions connexes