我很确定有人遇到过这种疯狂的事情,只是不知道如何问谷歌大叔。当将引文下载到或Zotero
或JabRef
任何引文管理器时,一些期刊只会提供名字作为缩写,例如B. K.
其他期刊会提供全名,导致混淆的条目,其中一些条目有一个具有全名的特定作者,而其他条目只有缩写。因此,这会导致问题,例如biblatex
因为它考虑了Doe, John
和Doe, J.
两个不同的作者,导致诸如在文内引文中放置名字首字母之类的行为,需要通过解决此问题,uniquename=false
从而导致被忽略(可能仍然是为了解决非唯一性)。这实际上是非常烦人的问题。显然,一种方法是手动逐一浏览参考文献并处理它。但这非常繁琐。maxcitenames=3
mincitenames=1
例如,JabRef
和Zotero
都有处理重复条目的工具。JabRef
此外,还有一种方法可以显示bib
数据库中的错误。但是你如何自动处理这些作者的混乱情况呢?(理想情况下,我会设想一个工具,它只向你显示一堆具有相同姓氏和名字首字母的 bib 项目,然后你选择“好的,我想将完整的名字复制到这些条目中”或任何其他合理的方法来处理这个问题,而无需花费数小时手动修改条目,最好尽可能保留完整的名字)
TeX
(我觉得对于某些过分关心的人来说这可能被认为是题外话,但我认为这与参考书目非常相关,bibtex
具体来说)
答案1
您可以自己编写此功能,例如使用Text::BibTeX
提供文件解析功能的Perl 库.bib
。
以下代码对输入.bib
文件执行两次传递。第一次传递中,它为每个条目的每个作者的姓氏+首字母组合找到最长的名字。第二次传递中,它用第一次传递中存储的长版本替换所有名字。
有一些簿记实际上是从姓氏、名字、前缀(“von”部分)和后缀(“jr”部分)中重建名称,因为我不清楚是否可以保留现有对象Text::BibTeX::Name
并仅修改它的一部分(此处为部分first
)同时保持其余部分不变 - 所以我决定从各部分构建一个名称字符串并在条目末尾手动连接所有名称。
代码:
use Text::BibTeX;
# first pass: store the longest name for each last name+initial combination
my $bibfile = Text::BibTeX::File->new("$ARGV[0]") or die "error: $ARGV[0] not found\n";
while ($entry = Text::BibTeX::Entry->new($bibfile)){
@names = $entry->names('author');
# loop all authors
foreach $name (@names){
$last = join(' ', $name->part('last'));
$first = join(' ', $name->part('first'));
$char1 = substr($first,0,1);
# if the last name with this initial is seen before,
if(exists($namemap{$last.$char1})){
# check if the new first name is longer than the previous one
if(length($first) > length($namemap{$last.$char1})){
# if yes, store it, otherwise do nothing (i.e., keep the previous one)
$namemap{$last.$char1} = $first;
}
# last name with this initial has not been seen, store the first name
}else{
$namemap{$last.$char1} = $first;
}
}
}
$bibfile->close;
# second pass: replace the names
my $bibfile = Text::BibTeX::File->new("$ARGV[0]") or die "error: $ARGV[0] not found\n";
my $newfile = Text::BibTeX::File->new(">$ARGV[1]") or die "error: cannot write $ARGV[1]\n";
while ($entry = Text::BibTeX::Entry->new($bibfile)){
@newnames = ();
@names = $entry->names('author');
# loop each author
foreach $name (@names){
$last = join(' ', $name->part('last'));
$currfirst = join(' ', $name->part('first'));
$char1 = substr($currfirst,0,1);
# find the first name stored in the first pass
$first = $namemap{$last.$char1};
# reconstruct the name as von last, jr, first
$reconstructname = "";
if($name->part('von')){
$reconstructname .= $name->part('von')." ";
}
$reconstructname .= $last.", ";
if($name->part('jr')){
$reconstructname .= $name->part('jr').", ";
}
$reconstructname .= $first;
# add reconstructed name to list of authors
push(@newnames, $reconstructname);
}
# set full author field as all authors separated by "and"
$entry->set('author', join(' and ', @newnames));
# write the entry to the bib file
$entry->write($newfile);
}
输入.bib
文件示例:
@misc{doeabbr,
author = {J. Smith and J. Doe and C. Doe},
title = {The Shorter The Better},
year = {2009}
}
@misc{doefull,
author = {Doe, John and Smith, Jane Mary and Doe, Charlie},
title = {Full Names Are Important},
year = {2010}
}
命令行:
perl script.pl inputfile.bib outputfile.bib
生成的输出文件:
@misc{doeabbr,
author = {Smith, Jane Mary and Doe, John and Doe, Charlie},
title = {The Shorter The Better},
year = {2009},
}
@misc{doefull,
author = {Doe, John and Smith, Jane Mary and Doe, Charlie},
title = {Full Names Are Important},
year = {2010},
}