EMACS/Python/Winmergeを使用して2つのDIFFファイルのマッピングライン番号

StackOverflow https://stackoverflow.com/questions/8337098

  •  26-10-2019
  •  | 
  •  

質問

わずかに異なる次の2つのファイルを検討してください。

foo (古いバージョン):

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

foo (新しいバージョン):

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

ご覧のとおり、キャラクター ef 新しいファイルで導入されています。

古いファイルに対応する行番号のセットがあります…たとえば 1, 3, 、 と 4 (文字に対応 a, c, 、 と d).

これら2つのファイルでマッピングを行う方法はありますか。これにより、新しいファイルで対応する文字の行番号を取得できますか?

たとえば、結果は次のとおりです。

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

残念ながら、私は(作業用の編集者)、Python、Winmergeのみを自由に使えるものです。

役に立ちましたか?

解決

必要なのはaです 文字列検索アルゴリズム テキスト内で検索したい複数のパターン(Fooの古いバージョンの行)がある場合(Fooの新しいバージョン)。 ラビンカープ アルゴリズムは、この種のタスクのそのようなアルゴリズムの1つです。私はそれをあなたの問題に適応させました:

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)

2つのファイルが呼び出されていると仮定します old_foo.txtnew_foo.txt 次に、この関数を次のように呼びます。

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

私があなたのデータを試してみたとき、それは印刷しました:

1 ===> 1
3 ===> 4
4 ===> 6

他のヒント

あなたはそれをすべて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))))))

走る、

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

-> (1 4 6)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top