考虑以下两个略有不同的文件:
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
如您所见,新文件中引入了字符e
和f
。
我有一组与旧文件对应的行号...比如,1
,3
和4
(对应于字母a
,{{1} }和c
)。
有没有办法对这两个文件进行映射,以便我可以在较新的文件中获取相应字符的行号?
E.G。,结果将是:
d
不幸的是,我只有emacs(有一个正在运行的ediff),Python和winmerge。
答案 0 :(得分:3)
您可以在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))))))
要跑步,
米 - : (get-joint-index "/tmp/old" '(1 3 4) "/tmp/new")
- &GT; (1 4 6)
答案 1 :(得分:2)
你需要的是一个string searching algorithm,你要在文本中搜索多个模式(来自旧版foo的行)(新版本的foo)。 Rabin-Karp算法就是这种算法的一种算法。我已经适应了你的问题:
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)
假设您的两个文件名为old_foo.txt
和new_foo.txt
,那么您可以像这样调用此函数:
linematcher('new_foo.txt', 'old_foo.txt', [1, 3, 4])
当我尝试使用您的数据时,它会打印出来:
1 ===> 1
3 ===> 4
4 ===> 6