问题陈述
我正在寻找一种方法来使用biber
的“工具模式”在大型文件上运行(CLI)命令,.bib
以便
- 仅从中提取那些字段
keywords = {}
包含用户可定义值的条目(如下mykeyword
例所示),并且 - 将结果条目写入新
.bib
文件。
例子
想象一个.bib
包含以下条目的文件:
@article{First,
[...]
keywords = {foo, bla},
}
@article{Second,
[...]
keywords = {test, foo},
}
@article{Third,
[...]
keywords = {bla},
}
在此文件上运行我正在寻找的“魔术命令”.bib
将匹配以下条目:
- 对于关键字
foo
:First
和Second
- 对于关键字
bla
:First
和Third
- 对于关键字
test
:Second
我是什么不是寻找
- 由于超出此问题范围的各种原因,我真正想使用 的
biber
“工具模式”来解决这个问题(而不是其他工具,如bibexport
、bib2bib
或bibtool
)。 - 我正在寻找一种解决方案,它使用
.conf
文件作为biber
“工具模式”,并且不是依赖.tex
该流程中的任何文件。
最小(非)工作示例
这解决方案到相关问题使用 的biber
“工具模式”按文档类型(而不是按匹配的关键字)提取.bib
条目。具体来说,它似乎使用定制的 biber.conf
文件来识别不是通过 查找书籍<per_nottype>
,然后通过 从参考书目中排除这些书籍<map_step map_entry_null="1" />
。
但是,<per_notkeyword>
似乎不存在等效的标签,这就是为什么我猜测我的解决方案必须依赖于map_field_set
和的某种组合map_field_value
。但是,以下(非常临时!)示例无法按预期工作(即使对于它目前尝试实现的稍微简单的“反向”情况也是如此,即移除包含关键字的条目mykeyword
):
<?xml version="1.0" encoding="UTF-8"?>
<config>
<output_align>true</output_align>
<output_fieldcase>lower</output_fieldcase>
<sourcemap>
<maps datatype="bibtex" map_overwrite="1">
<map>
<map_step map_field_set="KEYWORDS" map_field_value="mykeyword"/>
<map_step map_entry_null="1" />
</map>
</maps>
</sourcemap>
</config>
有没有办法修改上述.conf
文件以biber
获得所需的结果?
加分项(其实不是)
额外的好处是通用的解决方案,它允许我将目标关键字指定为命令行参数,同时只依赖于单个.conf
文件。
答案1
以下 shell 脚本解决了该问题的所有方面,包括将所需关键字作为命令行参数传递的能力。请注意,它只接受单身的关键字,但是它可以包含空格(只要在脚本调用中关键字用双引号括起来)。
Shell 脚本bibextract.sh
#!/bin/bash
# Write temporary config file
# NOTE: Escapes " to \" and replaces $2 by second command-line argument
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<config>
<output_align>true</output_align>
<output_fieldcase>lower</output_fieldcase>
<sourcemap>
<!-- Main source: https://tex.stackexchange.com/a/616241/38212 -->
<maps datatype=\"bibtex\">
<!-- Step 1: Remove all entries that do not contain any keywords whatsoever (necessary because later 'map_notmatch' is FALSE in that case) -->
<map>
<map_step map_notfield=\"keywords\" map_final=\"1\"/> <!-- map_final=\"1\" means that next step is only executed if this condition is met -->
<map_step map_entry_null=\"1\"/> <!-- remove entry from output -->
</map>
<!-- Step 2: From remaining entries, remove any where keyword does /not/ match regular expression -->
<map>
<map_step map_field_source=\"keywords\" map_notmatch=\".*${2}.*\" map_final=\"1\"/>
<map_step map_entry_null=\"1\"/>
</map>
</maps>
</sourcemap>
</config>" > /tmp/by_keyword.conf
# Run biber in "tool mode" using that temporary config file
biber --tool --configfile=/tmp/by_keyword.conf --output-file $3 $1
# Clean up
rm $1.blg
rm /tmp/by_keyword.conf
exit 0
- 存到
./bibextract.sh
- 使可执行文件:
chmod +x ./bibextract.sh
用法
$ ./bibextract.sh input.bib mykeyword output.bib
$ ./bibextract.sh input.bib "my keyword with spaces" output.bib
解释
biber
该脚本首先将的“工具模式”的临时配置文件写入/tmp/by_keyword.conf
,该配置文件实现了受以下启发的两步映射过程:这个帖子:
- 删除所有不包含任何关键字的条目(这是必要的,因为在这种情况下
map_notmatch
是后者FALSE
) - 从剩余条目中删除任何 where 关键字不是匹配正则表达式(本质上
.*my keyword with spaces.*
)
然后,Biber 使用该配置以“工具模式”运行,然后临时配置文件(以及.blg
在此过程中创建的文件)被再次删除。
test.bib
测试脚本的示例
@book{FooBla,
title = {FooBla},
author = {FooBla},
keywords = {foo, bla},
}
@article{MooFoo,
title = {MooFoo},
author = {MooFoo},
keywords = {moo, foo},
}
@misc{Bla,
title = {Bla},
author = {Bla},
keywords = {bla},
}
@book{BlaThe-WordFoo,
title = {BlaThe-WordFoo},
author = {BlaThe-WordFoo},
keywords = {bla, the word, foo},
}
@collection{NoKeywords,
title = {NoKeywords},
author = {NoKeywords},
}
测试程序
$ ./bibextract.sh test.bib foo foo.bib
$ ./bibextract.sh test.bib bla bla.bib
$ ./bibextract.sh test.bib moo moo.bib
$ ./bibextract.sh test.bib "the word" the-word.bib
生成的.bib
文件
foo.bib
@book{FooBla,
author = {FooBla},
keywords = {foo,bla},
title = {FooBla},
}
@article{MooFoo,
author = {MooFoo},
keywords = {moo,foo},
title = {MooFoo},
}
@book{BlaThe-WordFoo,
author = {BlaThe-WordFoo},
keywords = {bla,the word,foo},
title = {BlaThe-WordFoo},
}
bla.bib
@book{FooBla,
author = {FooBla},
keywords = {foo,bla},
title = {FooBla},
}
@misc{Bla,
author = {Bla},
keywords = {bla},
title = {Bla},
}
@book{BlaThe-WordFoo,
author = {BlaThe-WordFoo},
keywords = {bla,the word,foo},
title = {BlaThe-WordFoo},
}
moo.bib
@article{MooFoo,
author = {MooFoo},
keywords = {moo,foo},
title = {MooFoo},
}
the-word.bib
@book{BlaThe-WordFoo,
author = {BlaThe-WordFoo},
keywords = {bla,the word,foo},
title = {BlaThe-WordFoo},
}