我有一个大型文本文件 (.bib),其中某些字段有很多重复条目。本质上,该文件是一个.bib
-file(更多信息这里) 大约有 1000 个条目。内容结构如下:
@Article{Apak_2011_Financialriskmanagement,
Title = {Financial risk management in renewable energy sector: Comparative analysis between the European Union and Turkey},
Author = {Apak, Sudi and Atay, Erhan and Tuncer, Güngör},
Journal = {Procedia - Social and Behavioral Sciences},
Pages = {935--945},
Volume = {24},
Year = {2011},
Doi = {10.1016/j.sbspro.2011.09.013},
ISSN = {1877-0428},
}
@Incollection{Berger_1992_OutputMeasurementin,
Title = {Output Measurement in the Service Sectors},
Author = {Berger, Allen N. and Humphrey, David B.},
Crossref = {Griliches_1992_OutputMeasurementinb},
Pages = {245--300 book},
Year = {1992},
Publisher = {University of Chicago Press},
Date = {1992-10-04},
Booktitle = {Output Measurement in the Service Sectors},
Editor = {Griliches, Zvi and Berndt, Ernst R. and Bresnahan, Timothy F. and Manser, Marilyn}
}
@Book{Bogenstahl_2012_ManagementvonNetzwerken,
Title = {Management von Netzwerken},
Author = {Bogenstahl, Christoph},
Publisher = {Gabler},
Date = {2012-01-01},
ISBN = {978-3-8349-3572-4},
Series = {Strategisches Kompetenz-Management}
}
您将看到,Year
第一个源仅定义了 。然而,第二个源同时定义了Year
和Date
。
编辑:事后看来一切都很清楚
我刚刚注意到我总是需要这个Year
字段,因为我通过贾布雷夫。而为了生成 bibtex-key,JabRef 需要 -field 。我的意思是,到目前为止,Year
我还没有找到借助-fieldyyyy
的 -part生成 bibtex-key 的选项,所以我将编辑条件。Date
那么,有没有办法可以执行以下操作:
- 如果仅为
Date
源条目定义了,则将前 4 位数字(yyyy)复制到Year
。 - 如果只有
Year
定义,则将四位数字复制到Date
。 - 如果
Date
和Year
都已定义,则不执行任何操作。
以下是以前的情况,当时我还没有想过 JabRef 的内部运作
旧条件,如果有人想准备 .bib 文件以供 biblatex 使用并且在他的文件中混合了Date
和字段,那么仍然相关:Year
- 如果仅为
Date
源条目定义,则不执行任何操作。 Date
如果和都已Year
定义,则将 括号中的内容复制Date
到 括号中Year
。这里的要点是,Date
可能包含比 更多的信息(按照 yyyy-mm-dd 格式)Year
,所以这正是我写下这些“条件”的原因。无论 的内容如何Year
,Date
都更重要。除非我在输入所有信息时犯了一些错误,否则 的前 4 位数字当然Date
应该等于。Year
- 如果只有定义,则可简单地
Year
将该术语替换为。Year
Date
几点说明:
如果这些信息在这种情况下能有所帮助:我使用 Windows 7 和 Xubuntu 14.04。我有 Office 2010,如果可以在这里使用的话……或者我很乐意在 Xubuntu 上使用某种工具,我不知道。
我已经检查过了,显然我不能为此使用 JabRef,它有点太复杂了。
答案1
我会用 perl 来解决这个问题。http://search.cpan.org/~ambs/Text-BibTeX-0.70/lib/Text/BibTeX.pm应该有帮助。例如:
use Text::BibTeX;
$bibfile = new Text::BibTeX::File "foo.bib";
$newfile = new Text::BibTeX::File ">newfoo.bib";
while ($entry = new Text::BibTeX::Entry $bibfile) {
next unless $entry->parse_ok;
if ($has_year = $entry->exists ('year')) {
$year = $entry->get('year');
}
if ($has_date = $entry->exists ('date')) {
$date = $entry->get('date');
}
if ($has_year and ! $has_date) {
$entry->set('date', $year);
}
if ($has_date and ! $has_year) {
$entry->set('year', substr($date, 0, 4));
}
$entry->write ($newfile);
}
答案2
笔记:此解决方案适用于原始需求集。需要更新才能与当前版本配合使用。而且,perl
基于此的答案无论如何都更简洁 :-)
如果您不介意创建一些临时文件,这可以作为一个起点:将其复制到文件中并设置可执行标志(chmod +x file
)
#!/bin/bash
INFILE=$1
# split the file first
awk '/^@/{x="tmp__"++i}{print > x;}' $INFILE
# process individual files
for file in tmp__* ; do
DATE=$(grep "^[[:space:]]*Date" $file | sed "s/.*{\(.*\)}.*/\1/g")
YEAR=$(grep "^[[:space:]]*Year" $file | sed "s/.*{\(.*\)}.*/\1/g")
# Both year and date. Substitute year with date
if [[ -n "$DATE" && -n "$YEAR" ]] ; then
sed -i "s/\(^[[:space:]]*Year.*\)${YEAR}\(.*\)/\1${DATE}\2/g" $file
fi
# Only year
if [[ -z "$DATE" && -n "$YEAR" ]] ; then
sed -i "s/\(^[[:space:]]*\)Year/\1Date/g" $file
fi
done
# concatenate the files back
cat tmp__* > out.bib
rm -f tmp__*
该脚本的作用是:
- 接受一个参数 - 输入文件名
- 将文件拆分为多个临时文件,每个文件仅包含一条记录
- 遍历文件并根据您的指示单独处理它们(前提是我理解它们很好,即 - 见下文)
- 将处理后的文件连接到 out.bib 中
- 删除临时文件。
该脚本不会修改原始输入文件,因此它应该是非常安全的。
我仍然不完全清楚您的要求,因此,如果您尝试一下并发现某些情况没有达到您的预期 - 请随时告诉我,我会尝试改进它。