我有一个如下所示的 CSV 文件
testa, 123
testb, 456
testc, 789
如何处理 CSV 文件以获得以下结果?
\newcommand{\testa}{123}
\newcommand{\testb}{456}
\newcommand{\testc}{789}
答案1
\documentclass{article}
\newread\zz
\def\xpar{\par}
\def\zzdef#1,#2#3 \relax{\expandafter\def\csname#1\endcsname{#2#3}}
\openin\zz=zz.csv
\loop
\ifeof\zz
\else
\read\zz to \tmp
\ifx\tmp\xpar\else
\expandafter\zzdef\tmp\relax
\fi
\repeat
\begin{document}
testa is [\testa]
testb is [\testb]
testc is [\testc]
\end{document}
答案2
您可以使用以下方法处理 CSV 的每一行datatool
的\DTLforeach
处理器并为每个处理器创建一个宏:
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{data.csv}
testa, 123
testb, 456
testc, 789
\end{filecontents*}
\usepackage{datatool}
\begin{document}
\DTLloaddb[noheader, keys={varname,datavalue}]{data}{data.csv}
\DTLforeach{data}{\varname=varname,\datavalue=datavalue}{%
\expandafter\edef\csname\varname\endcsname{\datavalue}%
}
\verb|\testa|: \testa
\verb|\testb|: \testb
\verb|\testc|: \testc
\end{document}
答案3
和expl3
:
\begin{filecontents*}{\jobname.csv}
testa, 123
testb, 456
testc, 789
\end{filecontents*}
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\definefromcsv}{m}
{
\schneider_definefromcsv:n { #1 }
}
\cs_new_protected:Nn \schneider_definefromcsv:n
{
\ior_open:Nn \g_tmpa_ior { #1 }
\ior_map_inline:Nn \g_tmpa_ior
{
\__schneider_define:n { ##1 }
}
\ior_close:N \g_tmpa_ior
}
\cs_new_protected:Nn \__schneider_define:n
{
\clist_set:Nn \l_tmpa_clist { #1 }
\cs_new:cpx { \clist_item:Nn \l_tmpa_clist { 1 } }
{
\clist_item:Nn \l_tmpa_clist { 2 }
}
}
\ExplSyntaxOff
\begin{document}
\definefromcsv{\jobname.csv}
\verb|\testa|: --\testa--
\verb|\testb|: --\testb--
\verb|\testc|: --\testc--
\end{document}
一些注意事项。\ior_map_inline:Nn
尾随空格不会被删除,但\clist_set:Nn
会处理这个问题,因为它会在规范化 clist 时删除项目周围的前导和尾随空格。\edef
诸如这样的“危险”宏的存在\textbf
不是问题,因为它\clist_item:Nn
会以“不可扩展形式”返回项目,即被\exp_not:n
(\unexpanded
在 eTeX 术语中)包围。
答案4
这是 Werner 的答案(或 David 的答案)的稍微更直观的版本,使用 datatool
和etoolbox
。
\RequirePackage{filecontents}
\begin{filecontents*}{\jobname.csv}
testa, 123
testb, 456
testc, 789
\end{filecontents*}
\documentclass{article}
\usepackage{etoolbox}
\usepackage{datatool}
\begin{document}
\DTLloaddb[noheader,keys={name,value}]{csnames}{\jobname.csv}
\DTLforeach*{csnames}{\myname=name,\myvalue=value}{
\csxdef{\myname}{\expandonce{\myvalue}}
}
\verb|\testa|: \testa
\verb|\testb|: \testb
\verb|\testc|: \testc
\end{document}