我有两个.bib
文件想要用在我的参考书目中。条目不重叠。我找到了不少关于此问题的论坛主题,但没有一个真正让我满意。所以我的想法是将两个文件合并为一个.bib
文件,我将在 中使用该文件.tex
。最方便的是,这将在 LaTeX 中完成(因此我不使用bibtool
或参考软件)。因此,我制作了一个宏来合并两个文件:
\newwrite\bibwrite
\newcommand{\concatbib}[2]{%
\begingroup
\IfFileExists{#1}%
{\CatchFileDef{\bibone}{#1}{}}
{\let\bibone\empty}
\IfFileExists{#2}%
{\CatchFileDef{\bibtwo}{#2}{}}
{\let\bibtwo\empty}%
\immediate\openout\bibwrite=MyBib.bib\relax
\immediate\write\bibwrite{\bibone \bibtwo}%
\immediate\closeout\bibwrite
\endgroup
}
这基本上取自另一个问题(如何以“追加”模式打开文件?)。现在的问题是 Latex 想要解释文件内容,而诸如 之类的东西\noexpand
并\detokenize
没有按预期工作。所以我必须逐字逐句地阅读它,我根据 Martin Scharrer 的回答尝试了:控制命令参数。
\def\alltext{
\begingroup
\let\do\@makeother % define \do to change the category code of its argument to 'other'
\dospecials % makro that is a string of every special character preceeded with \do -> all catcodes are changed
\all@text
}
\def\all@text#1{
\endgroup
#1
}
我会在其他宏中使用它。但是,单独测试时,我得到了错误“使用\all
不匹配其定义” \alltext
,我认为我在这里忽略了一个重点。
- 我认为我将 的定义放在
\all@text
之后,\alltext
这样我就可以关闭该组,根据我的理解,我需要定义 catcodes 被更改的区域。但我不明白为什么\all@text
的定义中应该已经知道\alltext
? - 到目前为止,我明白
\@...
命令是原始命令,但我认为这只是一种符号。还有更多吗? - 有没有什么办法可以让这段代码运行起来?
答案1
我不确定我是否遗漏了你的设置,但你真的需要合并这两个.bib
文件吗?如果它们被命名为biblio1.bib
和biblio2.bib
,BibTeX 和 LaTeX 可以通过以下语句轻松访问这两个文件
\bibliography{biblio1,biblio2}
如果您使用该biblatex
软件包,我理解首选样式是使用一对单独的\addbibresource
语句(参见软件包的 3.6.1 节)手动的):
\addbibresource{biblio1.bib}
\addbibresource{biblio2.bib}
.bib
请注意,使用该命令时必须提供文件扩展名\addbibresource
,而使用该命令时不应提供此扩展名\bibliography
。
答案2
如果您确实想在 TeX 级别执行此操作(这实际上不是必需的,因为您可以输入.bib
任意数量的文件),这里有一组宏可以执行此操作。您可以将任意数量的 bib 文件名(不带扩展名)作为强制参数\concatbib
,以逗号分隔。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% The document level command
\NewDocumentCommand{\concatbib}{ O{output} m }
{
\heinrich_concatbib:nn { #1 } { #2 }
}
% Variables and messages
\ior_new:N \l__heinrich_input_stream
\iow_new:N \l__heinrich_output_stream
\msg_new:nnnn { concatbib } { file-exist }
{ File~`#1'~exists.~Not~overwriting.}
{ The~file~`#1'~already~exists.~I'll~ignore~this~command. }
% Internal functions
% First we check that the named output file doesn't exist
\cs_new_protected:Npn \heinrich_concatbib:nn #1 #2
{
\file_if_exist:nTF { #1.bib }
{
\msg_error:nnn { concatbib } { file-exist } { #1.bib }
}
{
\__heinrich_concatbib_aux:nn { #1 } { #2 }
}
}
% If we're writing, we open an output stream and cycle
% through the second argument, a comma separated list
% of bib file names
\cs_new_protected:Npn \__heinrich_concatbib_aux:nn #1 #2
{
\iow_open:Nn \l__heinrich_output_stream { #1.bib }
\clist_map_inline:nn { #2 } { \__heinrich_read_write:n { ##1 } }
\iow_close:N \l__heinrich_output_stream
}
% At each step we read each line of the current .bib file
% and write it to the output stream
\cs_new_protected:Npn \__heinrich_read_write:n #1
{
\ior_open:Nn \l__heinrich_input_stream { #1.bib }
\ior_str_map_inline:Nn \l__heinrich_input_stream
{ \iow_now:Nn \l__heinrich_output_stream { ##1 } }
\ior_close:N \l__heinrich_input_stream
}
\ExplSyntaxOff
% This will concatenate in `output.bib'
\concatbib{foo1,foo2}
% This will concatenate in `foo.bib'
\concatbib[foo]{foo1,foo2}
答案3
嗯...我非常赞成使用正确的工具来完成任务。因此,虽然这在智力上很有启发,但我不会在 LaTeX 中实现这一点,而只是使用基本的操作系统功能(不需要 bibtool 或其他花哨的东西):
在 Linux/UNIX/MacOS 上,在相应目录中打开 bash(或任何 shell 或终端)并输入:
cat bibone.bib bibtwo.bib >MyBib.bib
在 Windows 上,打开 CMD 提示符并输入:
type bibone.bib bibtwo.bib >MyBib.bib
在这两个系统上您还可以附加>>
通过使用而不是 来重定向输出到现有的 MyBib.bib >
。