Display line numbers in two diff files with emacs / python / winmerge

Consider the following two files, which are slightly different:

foo (old version):

 <Line 1> a <Line 2> b <Line 3> c <Line 4> d 

foo (new version):

 <Line 1> a <Line 2> e <Line 3> b <Line 4> c <Line 5> f <Line 6> d 

As you can see, the characters e and f are entered in the new file.

I have a set of line numbers corresponding to a high file ... let's say 1 , 3 and 4 (matches the letters a , c and d ).

Is there a way to do the matching through these two files so that I can get the line numbers of the corresponding characters in the newer file?

EG, the result will be:

 Old file line numbers (1,3,4) ===> New File line numbers (1,4,6) 

Unfortunately, I only have emacs (with working ediff), Python and winmerge at my disposal.

+4
source share
2 answers

What you need is a string search algorithm where you have several patterns (strings from the old version of foo) that you want to find for the text (new version of foo). The Rabin-Karp algorithm is one such algorithm for this kind of problem. I adapted it to your problem:

 def linematcher(haystack, needles, lineNumbers): f = open(needles) needles = [line.strip() for n, line in enumerate(f, 1) if n in lineNumbers] f.close() hsubs = set(hash(s) for s in needles) for n, lineWithNewline in enumerate(open(haystack), 1): line = lineWithNewline.strip() hs = hash(line) if hs in hsubs and line in needles: print "{0} ===> {1}".format(lineNumbers[needles.index(line)], n) 

Assuming your two files are called old_foo.txt and new_foo.txt , you call this function as follows:

 linematcher('new_foo.txt', 'old_foo.txt', [1, 3, 4]) 

When I tried to use your data, it printed:

 1 ===> 1 3 ===> 4 4 ===> 6 
+2
source

You can do all this in Emacs:

 (defun get-joint-index (file-a index file-b) (let ((table (make-hash-table :test #'equal))) (flet ((line () (buffer-substring-no-properties (point-at-bol) (point-at-eol)))) (with-temp-buffer (insert-file file-b) (loop for i from 1 do (puthash (line) i table) while (zerop (forward-line)))) (with-temp-buffer (insert-file file-a) (loop for i in index do (goto-line i) collect (gethash (line) table)))))) 

To execute,

M-: (get-joint-index "/tmp/old" '(1 3 4) "/tmp/new")

-> (1 4 6)

+3
source

Source: https://habr.com/ru/post/1384045/


All Articles