从bibtex文件中提取选定条目的脚本


11

我有一个很大的bibtex文件,其中包含许多条目,每个条目都具有常规结构

@ARTICLE{AuthorYear,
item = {...},
item = {...},
item = {...},
etc
}

(在某些情况下,ARTICLE可能是一个不同的词,例如BOOK

我想做的是编写一个简单的脚本(最好仅是一个Shell脚本)以提取具有给定AuthorYear的条目并将其放入新的.bib文件中。

我可以想象我可以通过AuthorYear识别条目的第一句,而通过单引号可以识别条目的末尾,}也许可以sed用来提取条目,但是我真的不知道该怎么做。有人可以告诉我我将如何实现这一目标吗?

可能应该是这样的

sed -n "/AuthorYear/,/\}/p" file.bib

但这由于}条目的第一项的关闭而停止,从而给出以下输出:

@ARTICLE{AuthorYear,
item = {...},

因此,我需要识别出这是否}是一行中唯一的字符,并且在这种情况下,只有“ sed”停止读取。


我只能稍微修改一下您的代码:sed -n "/AuthorYear/,/\}$/p"。注意$符号。它工作正常,除了它不打印}bibitem 的结尾。顺便说一句,使用是sed必要的吗?
巴伦2013年

@Barun的使用sed根本没有必要,我只是认为那是最简单的选择。我想出了一个略有不同的代码:sed -n "/AuthorYear/, /^ *\}/p"它似乎完全可以实现我想要的功能,包括关闭}和纠正空格(如有)
Michiel 2013年

Answers:


2

以下Python脚本执行所需的过滤。

#!/usr/bin/python
import re

# Bibliography entries to retrieve
# Multiple pattern compilation from: http://stackoverflow.com/a/11693340/147021
pattern_strings = ['Author2010', 'Author2012',]
pattern_string = '|'.join(pattern_strings)
patterns = re.compile(pattern_string)


with open('bibliography.bib', 'r') as bib_file:
    keep_printing = False
    for line in bib_file:
        if patterns.findall(line):
            # Beginning of an entry
            keep_printing = True

        if line.strip() == '}':
            if keep_printing:
                print line
                # End of an entry -- should be the one which began earlier
                keep_printing = False

        if keep_printing:
            # The intermediate lines
            print line,

就个人而言,当过滤逻辑变得复杂时,我更喜欢使用脚本语言。也许这至少在可读性方面具有优势。


小心,嵌套{}s 的条目很多。如果您可以确保条目以结束\n},则可以以^}
vonbrand

8

我建议您将一种语言与经过战斗验证的BibTeX库一起使用,而不要重蹈覆辙。例如

#!/usr/bin/env perl
use strict;
use warnings;
use autodie;
use BibTeX::Parser;

open my $fh, '<', $ARGV[0];
my $parser = BibTeX::Parser->new($fh);
my @authoryear;
while (my $entry = $parser->next) {
    if ($entry->parse_ok) {
        if ($entry->key eq "AuthorYear") {
            push @authoryear, $entry;
        }
    }
    else {
        warn "Error parsing file: " . $entry->error;
    }
}

# I'm not familiar with bibtex files, so this may be insufficient
open my $out, '>', "authoryear.bib";
foreach my $entry (@authoryear) {
    say $out $entry->raw_bibtex;
}

您可能必须安装模块: cpan install BibTeX::Parser


1

现在,我们还有Python bibparsing模块,该模块允许使用Python分析BibTeX数据库。例如,我使用以下脚本来计算合作论文中的作者数量:

#!/usr/bin/python
import sys
import bibtexparser as bp
with open(sys.argv[1]) as bibtex_file:
    bd = bp.load(bibtex_file)
    for art in bd.entries_dict:
    print("*********")
    ae = bd.entries_dict[art]
    print(ae[u'title'])
    auths=ae[u'author'].split(" and ")
    print(len(auths))
    print(auths[0]+" --- "+auths[-1])


0

这是一个Bash脚本,它读取每一行并使用正则表达式匹配来提取其头部具有所需模式的每个条目。您可以称之为getbibs

#!/usr/bin/env bash
# usage: ./getbibs pattern input.bib output.bib

while read entry; do
    if [[ $entry =~ ^@.*{$1,$ ]]; then
        printf "%s\n" "$entry" >> "$3"
        while read item; do
            [[ $item =~ ^@.*$ ]] && break
            printf "%s\n" "$item" >> "$3"
        done
    fi
done < "$2"

要提取作者年份为1989的所有条目,您可以执行以下操作:

$ chmod +x ./getbibs
$ ./getbibs 1989 file.bib author.bib

它可能存在一些我尚未测试过的问题,但似乎可以完成该任务。


0

只是为了完整起见,我自己弄清楚了自己的方式,虽然不如其他方式好,但它确实有效:

entries=( AuthorYear1 AuthorYear2 )
for entry in "${entries[@]}" do
     sed -n "/"${entry}"/, /^ *\}/p" refs.bib 
done

它可以从命令行运行,也可以放在bash脚本中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.