自动解析 .bib 数据库中的重复引用键

自动解析 .bib 数据库中的重复引用键

我目前的工作流程是

  1. 编辑引用数据库在线
  2. wget http://www.citeulike.org/bibtex/user/MYUSER/tag/MYTAG?key_type=4
  3. biber biblio
  4. pdflatex biblio

其中biblio.tex是使用 生成的参考书目/参考文献列表文件\nocite{*}

问题在于,生成 AuthorYearTitle 键(key_type=4wget上面的 URL 中)的 CiteULike 算法可能会产生冲突,即两个具有相同键的不同条目。

虽然这肯定是 CiteULike 的错误,但我想通过在和之间插入另一个步骤来修补此问题,wgetbiber步骤重写.bib数据库以解析重复的键,在重复的 AuthorYearTitle 键后插入尾随的“a”、“b”...字母。(编辑:我想保留一个 AuthorYearTitle 键,以防参考书目需要进一步编辑。)

我想要一个不需要用户干预的解决方案,以便步骤 2.、3.、4.... 可以在脚本中运行。

我无法找到这个(简单?)问题的现有解决方案,在重新发明轮子之前,我想在这个论坛上寻求建议。

笔记

通过省略参数key_type=4,可以得到唯一的数字键(citeulike:123456),因此一个可能的策略是使用更强大的密钥生成器并忘记由 CiteULike 生成的密钥。

答案1

由于您使用的是\nocite{*},因此您不需要 bib 标签来表示任何有意义的内容。因此,一个简单的解决方案就是.bib用一些随机字符序列替换文件中的所有标签(或附加一个,见下文)。对我来说,这有效:

sed -i -e 's~^@\(.\+\){.\+,$~(echo @\1{; cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w 8 | head -1; echo ,) | paste -sd ""~e' biblio.bib

这是起什么作用的?

sed 

好吧,打电话sed

-i 

进行内联替换

-e 

使用扩展正则表达式(用于捕获组和替换)

'

开始sed命令

s

代替

~

替换起始分隔符

^@\(.\+\){.\+,$

搜索行首,,@一组非空白,后跟{,另一组非空白,,,行尾;例如,@article{AuthorYear,

~

替换中间分隔符

(echo @\1{; cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w 8 | head -1; echo ,) | paste -sd ""

替换为

  1. echo @,先前捕获的第一个非空白组,{
  2. 回显一个随机标签(cat通过head
  3. 回声,

(删除中间的换行符后paste

~

替代结束定界符

e

将替换作为 shell 命令调用,并使用输出作为替换文本

'

结束sed命令

biblio.bib

文件名

更新 1如果您想保留原始标签,只需捕获它们并附加随机标签:

sed -i -e 's~^@\(.\+\){\(.\+\),$~(echo @\1{\2_; cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w 8 | head -1; echo ,) | paste -sd ""~e' biblio.bib

更新 2这不是用随机标签替换,而是将ab、 ... 添加到标签中之前曾被见过;因此第一次出现的“AuthorYear”保持不变,第二次出现的变为“AuthorYeara”,依此类推。

echo > cache
sed -i -e 's~^@\(.\+\){\(.\+\),$~(echo @\1{\2; awk "BEGIN{printf \\\"%c\\\", 96+`grep \2 cache | wc -l`}" | sed "s/\\\`//"; echo \2 >> cache; echo ,) | paste -sd ""~e' biblio.bib

当然可以改为第二个“b”:

echo > cache
sed -i -e 's~^@\(.\+\){\(.\+\),$~(echo @\1{\2; awk "BEGIN{printf \\\"%c\\\", 97+`grep \2 cache | wc -l`}" | sed "s/a//"; echo \2 >> cache; echo ,) | paste -sd ""~e' biblio.bib

相关内容