我已从 Zotero 以 biblatex 格式导出参考书目。所有参考文献都包含日期字段,但现在包含年份字段。
是否有一种简单的方法(工具,脚本等)来转换日期字段或附加年份和月份字段?
例子:
@article{kattan_timeseries_2015, title = {基于时间序列事件的预测:基于遗传编程的无监督学习框架}, journaltitle = {信息科学}, 作者 = {Kattan, Ahmed 和 Fatima, Shaheen 以及 Arif, Muhammad}, 日期 = {2015-04} }
我想
@article{kattan_timeseries_2015, title = {基于时间序列事件的预测:基于遗传编程的无监督学习框架}, journaltitle = {信息科学}, 作者 = {Kattan, Ahmed 和 Fatima, Shaheen 以及 Arif, Muhammad}, 日期 = {2015-04}, 年份 = {2015}, 月 = {04} }
答案1
这是 Biber 在其工具模式下可以做到的事情。
不幸的是,这里最初建议的解决方案不久前就失效了。以下https://github.com/plk/biber/issues/301Biber 已调整,因此一切又能正常工作了。修复将在 Biber 2.15 中提供。对于中间版本,恐怕我无法提供基于 Biber 的简单解决方案。(也许bibtool
可以在这里提供帮助。)
Biber 版本 2.15 及以上
我们需要以下配置文件,例如,biber-date.conf
<?xml version="1.0" encoding="UTF-8"?>
<config>
<output_fieldcase>lower</output_fieldcase>
<datamodel>
<fields>
<field fieldtype="field" datatype="literal">year</field>
<field fieldtype="field" datatype="literal">month</field>
</fields>
<entryfields>
<field>year</field>
<field>month</field>
</entryfields>
</datamodel>
<sourcemap>
<maps datatype="bibtex">
<map map_overwrite="1">
<map_step map_field_source="date" map_match="[0-9]{4}-([0-9]{2})" map_final="1"/>
<map_step map_field_set="montha" map_field_value="$1"/>
</map>
<map map_overwrite="1">
<map_step map_field_source="date" map_match="([0-9]{4})" map_final="1"/>
<map_step map_field_set="yeara" map_field_value="$1"/>
</map>
</maps>
</sourcemap>
</config>
要转换文件运行date
中的字段.bib
biber --tool --configfile=biber-date.conf <yourbibfile>
对于示例文件augustus.bib
@article{kattan_timeseries_2015,
title = {Time-series event-based prediction: An unsupervised learning framework based on genetic programming},
journaltitle = {Information Sciences},
author = {Kattan, Ahmed and Fatima, Shaheen and Arif, Muhammad},
date = {2015-04}
}
@book{lorem,
title = {Lorem},
author = {Anne Uthor},
date = {2015}
}
@book{ipsum,
title = {Ipsum},
author = {Anne Uthor},
date = {2015-08-07},
}
augustus_bibertools.bib
输出(运行后可以找到biber --tool --configfile=biber-date.conf augustus.bib
)是
@article{kattan_timeseries_2015,
author = {Kattan, Ahmed and Fatima, Shaheen and Arif, Muhammad},
journaltitle = {Information Sciences},
month = {4},
title = {Time-series event-based prediction: An unsupervised learning framework based on genetic programming},
year = {2015},
}
@book{lorem,
author = {Uthor, Anne},
title = {Lorem},
year = {2015},
}
@book{ipsum,
author = {Uthor, Anne},
date = {2015-08-07},
title = {Ipsum},
}
旧版本的Biber
我们需要以下配置文件,名为 saybiber-date.conf
<?xml version="1.0" encoding="UTF-8"?>
<config>
<output_fieldcase>lower</output_fieldcase>
<sourcemap>
<maps datatype="bibtex" map_overwrite="1">
<map map_overwrite="1">
<map_step map_field_source="date" map_match="[0-9]{4}?-([0-9]{2}?)" map_final="1"/>
<map_step map_field_set="month" map_field_value="$1"/>
</map>
<map map_overwrite="1">
<map_step map_field_source="date" map_match="([0-9]{4}?)" map_final="1"/>
<map_step map_field_set="year" map_field_value="$1"/>
</map>
</maps>
</sourcemap>
</config>
正则表达式不是特别优雅,但第一个将字段的月份位置复制date
到month
字段,第二个将年份位置映射到year
字段。
现在你只需要运行biber --tool --configfile=biber-date.conf <yourbibfile>
在示例文件上augustus.bib
@article{kattan_timeseries_2015,
title = {Time-series event-based prediction: An unsupervised learning framework based on genetic programming},
journaltitle = {Information Sciences},
author = {Kattan, Ahmed and Fatima, Shaheen and Arif, Muhammad},
date = {2015-04}
}
@book{lorem,
title = {Lorem},
author = {Anne Uthor},
date = {2015}
}
@book{ipsum,
title = {Ipsum},
author = {Anne Uthor},
date = {2015-08-07},
}
augustus_bibertools.bib
输出(运行后可以找到biber --tool --configfile=biber-date.conf augustus.bib
)是
@article{kattan_timeseries_2015,
author = {Kattan, Ahmed and Fatima, Shaheen and Arif, Muhammad},
date = {2015-04},
journaltitle = {Information Sciences},
month = {04},
title = {Time-series event-based prediction: An unsupervised learning framework based on genetic programming},
year = {2015},
}
@book{lorem,
author = {Anne Uthor},
date = {2015},
title = {Lorem},
year = {2015},
}
@book{ipsum,
author = {Anne Uthor},
date = {2015-08-07},
month = {08},
title = {Ipsum},
year = {2015},
}
答案2
biber 解决方案不再有效。这似乎是设计使然,因为手动的(版本 2.14)说
日期被规范化为 DATE 字段。旧版 YEAR 字段永远不会以 BibTeX 格式的数据输出。
我使用年份的正则表达式解决方案来解决这个问题(可以类似地提取月份):
sed -e 's/\(.*\)date\(.*\)\([[:digit:]]\{4\}\).*\(\}.*\)/\1year\2\3\4/g' augustus.bib
答案3
在尝试了其他解决方案但均未成功后,我最终编写了一个 Python 脚本来处理文件列表。前提条件是日期单独占一行,并以规范格式 YYYY-MM-DD 书写。该程序可以处理多个文件 (FILES)。
import os
import re
FILES = ["bibliografia.bib","standards.bib","bibdoslivrosesas.bib"]
TEMP = "temp.bib"
for arquivo in FILES:
bak = arquivo+".bak"
try:
filew = open(TEMP,"w")
with open(arquivo,"r") as f:
for linha in f:
novalinha = linha.lstrip()
if novalinha[:4] == "date" or novalinha[:4] == "DATE":
regexp = "\{[0-9\-]+\}"
m = re.search(regexp,novalinha).group(0)
# get year
print(m)
informacao = m.split("-")
if len(informacao) == 1:
filew.write("year = "+informacao[0]+",\n")
if len(informacao) == 2:
filew.write("year = "+informacao[0]+"},\n")
filew.write("month = {"+informacao[1]+",\n")
if len(informacao) == 3:
filew.write("year = "+informacao[0]+"},\n")
filew.write("month = {"+informacao[1]+"},\n")
filew.write("day = {"+informacao[2]+",\n")
else:
filew.write(linha)
finally:
filew.close()
os.rename(arquivo,bak)
os.rename(TEMP,arquivo)
答案4
这是另一个版本,它确保像 urldate 这样的值不会变成 urlyear (@Sebastians 回答中会发生这种情况),并且不会用年份替换日期,而是创建两个新字段,一个用于年份,一个用于月份。
长话短说:
sed -r 's/([ \t]+)(date)([ \t={]+)([[:digit:]]{4})([^0-9]{1})([[:digit:]]{2})(.*)/\1\2\3\4\5\6\7\n \1year\3\4\7\n \month\3\6\7/g' inputfile.bib | bibtool -o outputfile.bib
解释:
为了使其正常工作,日期字段中不能包含日期。我自己的图书馆里没有,也从未见过,但要检查,请使用 ripgrep 或 grep 来验证没有:
rg -P '[ \t]日期.*\d{4}-\d{2}-\d{2}' work-bibliotek.bib
代替
(.*)
在捕获所有内容的正则表达式的开头,我使用
([ \t]+)
因此像 urldate 这样的字段就会被 urlyear 替换。此版本确实要求在字段名称“date”之前有一个空格。
通过在 sed 命令之前对 bibfile 运行 bibtool 可以轻松确保这一点:
bibtool -i input.bib -o output.bib
不要替换字段,而是创建两个新的字段,包括年份和月份。
使用 sed -r 时,您不必一直使用转义字符,这很令人困惑
我将其通过管道传输到 bibtool 并从那里输出,以使月份字段与其他字段对齐