Biber 版本 2.15 及以上

Biber 版本 2.15 及以上

我已从 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>

正则表达式不是特别优雅,但第一个将字段的月份位置复制datemonth字段,第二个将年份位置映射到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

解释:

  1. 为了使其正常工作,日期字段中不能包含日期。我自己的图书馆里没有,也从未见过,但要检查,请使用 ripgrep 或 grep 来验证没有:

    rg -P '[ \t]日期.*\d{4}-\d{2}-\d{2}' work-bibliotek.bib

  2. 代替

(.*)

在捕获所有内容的正则表达式的开头,我使用

([ \t]+)

因此像 urldate 这样的字段就会被 urlyear 替换。此版本确实要求在字段名称“date”之前有一个空格。

通过在 sed 命令之前对 bibfile 运行 bibtool 可以轻松确保这一点:

  bibtool -i input.bib -o output.bib
  1. 不要替换字段,而是创建两个新的字段,包括年份和月份。

  2. 使用 sed -r 时,您不必一直使用转义字符,这很令人困惑

我将其通过管道传输到 bibtool 并从那里输出,以使月份字段与其他字段对齐

相关内容