合并多个bibtex

总说

有时候,你写毕业论文之类的,你需要合并多篇论文中的bibtex到一个,从而可以使得你论文的所有bibtex的引用正常。
存在以下四种情况:

  1. 标题相同,label不同 -> 二者都保持(这是因为,你直接复制正文时,不需要更改标签了。两种标签都可以用,都引用相同的论文)

  2. 标题相同,label相同 -> 保留一个

  3. 标题不同,label相同 -> 二者保留,记录log中,人为后续处理

  4. 标题不同,label相同 -> 二者保留,记录到log中,人为后续处理

  5. 其他情况(这是为了防止不小心略过的论文)-> 检查原本所有bib文件中的论文,进行更新

import os
import re
from collections import defaultdict

def read_bib_file(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        content = file.read()
    entries = re.split(r'\n@', content)
    entries = ['@' + entry.strip() for entry in entries if entry.strip()]
    return entries

def extract_title(entry):
    title_match = re.search(r'title\s*=\s*{(.+?)}', entry, re.IGNORECASE)
    if title_match:
        return title_match.group(1).strip()
    return None

def extract_citation_key(entry):
    key_match = re.search(r'@\w+{(.+?),', entry)
    if key_match:
        return key_match.group(1).strip()
    return None

def combine_bib_files(file_paths):
    combined_entries = defaultdict(list)
    citation_key_entries = defaultdict(list)
    duplicates = []
    errors = []
    all_entries = []

    for file_path in file_paths:
        entries = read_bib_file(file_path)
        all_entries.extend(entries)  # Keep track of all entries for summary
        for entry in entries:
            title = extract_title(entry)
            citation_key = extract_citation_key(entry)
            if title and citation_key:
                combined_entries[title].append(entry)
                citation_key_entries[citation_key].append(entry)

    final_entries = []

    for title, entries in combined_entries.items():
        if len(entries) > 1:
            keys = set(extract_citation_key(entry) for entry in entries)
            if len(keys) > 1:
                duplicates.append((title, entries))
                final_entries.extend(entries)
            else:
                final_entries.append(entries[0])
        else:
            final_entries.append(entries[0])

    for key, entries in citation_key_entries.items():
        if len(entries) > 1:
            titles = set(extract_title(entry) for entry in entries)
            if len(titles) > 1:
                errors.append((key, entries))
    
    return final_entries, duplicates, errors, all_entries

def write_combined_bib_file(entries, output_file):
    with open(output_file, 'w', encoding='utf-8') as file:
        for entry in entries:
            file.write(entry + '\n\n')

def log_duplicates(duplicates, log_file):
    with open(log_file, 'w', encoding='utf-8') as file:
        for title, entries in duplicates:
            file.write(f"Title: {title}\n")
            for entry in entries:
                file.write(entry + '\n\n')
            file.write('-' * 80 + '\n')

def log_errors(errors, log_file):
    with open(log_file, 'w', encoding='utf-8') as file:
        for key, entries in errors:
            file.write(f"Citation Key: {key}\n")
            for entry in entries:
                file.write(entry + '\n\n')
            file.write('-' * 80 + '\n')

if __name__ == "__main__":
    # List of paths to your bib files
    bib_files = ['ref1.bib', 'ref2.bib', 'ref3.bib']

    # Combine entries from all files
    combined_entries, duplicates, errors, all_entries = combine_bib_files(bib_files)

    # Write the combined entries to a new file
    output_file = 'combined_ref.bib'
    write_combined_bib_file(combined_entries, output_file)
    
    # Log duplicates for manual merging
    duplicates_log_file = 'duplicates_log.txt'
    log_duplicates(duplicates, duplicates_log_file)

    # Log errors for manual checking
    error_log_file = 'error_log.txt'
    log_errors(errors, error_log_file)

    # Print summary information
    print(f"Combined bib file created: {output_file} with {len(combined_entries)} entries")
    print(f"Duplicates log created: {duplicates_log_file} with {len(duplicates)} entries")
    print(f"Error log created: {error_log_file} with {len(errors)} entries")

    for file in bib_files:
        entries = read_bib_file(file)
        print(f"{file}: {len(entries)} entries processed")
    print(f"Total unique entries combined: {len(combined_entries)}")
    print(f"Total entries processed: {len(all_entries)}")



Zotero是一个开源的参考文献管理工具,可以帮助用户收集、整理和引用学术文献。而BibTeX是一种用于管理参考文献的文件格式。在Zotero中使用BibTeX可以方便地导出和使用参考文献。 要在Zotero中使用BibTeX,首先需要下载并安装一个名为"Better BibTeX"的插件。你可以在https://retorque.re/zotero-better-bibtex/installation/下载.xpi文件,并在Zotero的主页面中的"工具"->"插件"中进行安装。安装完成后,需要重启Zotero。 在安装完成并重启后,你可以在Zotero的编辑菜单中找到"首选项",然后选择"Better BibTex"选项卡。在这里,你可以进行一些基础设置,如设置导出格式和标题字母大小写问题。 要导出BibTeX文件,你可以选择一个或多个文献条目,然后在菜单中选择"导出"->"Better BibTex"。这样就可以将选中的文献条目导出为BibTeX格式的文件。 在Overleaf中使用BibTeX文件,你可以将导出的BibTeX文件导入到Overleaf项目中。你可以在Overleaf的文件菜单中选择"导入"->"上传",然后选择你导出的BibTeX文件进行上传。 如果你的BibTeX文件中有太多的作者,你可以在BibTeX文件的开头加上一段代码来限制作者的数量。另外,在.tex代码中,你可以使用一条代码来引用BibTeX文件中的参考文献。 需要注意的是,如果你在Zotero中选择了"keep updated"选项,导出的BibTeX文件将会保持更新,并且手动添加的BibTeX条目将会被覆盖。如果你需要手动添加条目,可以同时使用两个BibTeX文件,一个用于Zotero同步,一个用于手动添加一些Zotero中没有的BibTeX条目。 希望这些信息对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值