
아래 코드는 내가 원하는 결과를 생성합니다. 이는 허용된 값 목록 중 하나가 아닌 XXX={<value>}
a가 포함된 행 목록입니다 .<value>
그러나 이 솔루션을 사용하려면 오류가 발생하기 쉬운 두 위치에 동일한 정보가 있어야 합니다. 그렇다면 grep -v
의 내용을 기반으로 매크로 시퀀스를 생성할 수 있는 방법이 있습니까 \ListOfAcceptableValues
?
내가 생각할 수 있는 무차별적인 해결책은 허용된 값 목록의 각 요소에 대해 여러 파일을 사용하는 것이지만 아마도 이 작업을 수행하는 더 우아한 방법이 있을 것이라고 생각합니다.
노트:
- MacOS에서 작동하는 데에만 필요하므로 모든 Unix 유틸리티를 사용할 수 있습니다.
cat
이 매크로의 실제 사용법을 더 잘 에뮬레이트하기 때문에 여기를 사용하고 있습니다 .
암호:
\documentclass{article}
\usepackage{datatool}
%\usepackage{filecontents}% Commented out to prevent overwriting FileA.tex
\begin{filecontents*}{FileA.tex}
XXX={AA}
some other tex content
XXX={YY}
XXX={BB}
and some more tex content
XXX={ZZ}
XXX={CC}
\end{filecontents*}
\begin{document}
\newcommand*{\ListOfAcceptableValues}{AA,BB,CC}%
%% How do I rewrite this to make use of \ListOfAcceptableValues
\immediate\write18{%
cat FileA.tex
| grep "XXX="
| grep -v AA
| grep -v BB
| grep -v CC
> FileB.tex
}
\DTLloadrawdb[noheader,keys={Problem}]{MyDB}{FileB.tex}%
\DTLdisplaydb{MyDB}
\end{document}
답변1
\def\foo#1,#2{| grep -v #1 \ifx\relax#2\else\expandafter\foo\expandafter#2\fi}
%% How do I rewrite this to make use of \ListOfAcceptableValues
\immediate\write18{%
cat FileA.tex
| grep "XXX="
\expandafter\foo\ListOfAcceptableValues,\relax
> FileB.tex
}
답변2
순수한 LaTeX(3) 솔루션; 그러나 초기 공백은 유지되지 않습니다.
\begin{filecontents*}{FileA.tex}
XXX={AA}
some other tex content
XXX={YY}
XXX={BB}
and some more tex content
XXX={ZZ}
XXX={CC}
\end{filecontents*}
\documentclass{article}
\usepackage{datatool,xparse}
\ExplSyntaxOn
\seq_new:N \g_grill_acceptable_seq
\seq_new:N \l__grill_temp_seq
\ior_new:N \l_grill_input_stream
\iow_new:N \l_grill_output_stream
\NewDocumentCommand{\SetAcceptableValues}{m}
{
\seq_gset_split:Nnn \g_grill_acceptable_seq { , } { #1 }
}
\NewDocumentCommand{\ExamineFile}{mm}
{% #1 = input file, #2 = output file
\grill_examine_file:nn { #1 } { #2 }
}
\cs_new_protected:Npn \grill_examine_file:nn #1 #2
{
\ior_open:Nn \l_grill_input_stream { #1 }
\iow_open:Nn \l_grill_output_stream { #2 }
\ior_open:Nn \l_grill_input_stream { #1 }
\iow_open:Nn \l_grill_output_stream { #2 }
\ior_map_inline:Nn \l_grill_input_stream
{ \__grill_lookup_line:n { ##1 } }
\iow_close:N \l_grill_output_stream
\ior_close:N \l_grill_input_stream
}
\cs_new_protected:Npn \__grill_lookup_line:n #1
{
\seq_set_split:Nnn \l__grill_temp_seq { = } { #1 }
\int_compare:nT { \seq_count:N \l__grill_temp_seq = 2 }
{
\tl_if_eq:nxT { XXX } { \seq_item:Nn \l__grill_temp_seq { 1 } }
{
\seq_if_in:NxF \g_grill_acceptable_seq
{ \seq_item:Nn \l__grill_temp_seq { 2 } }
{
\iow_now:Nx \l_grill_output_stream { #1 }
}
}
}
}
\cs_generate_variant:Nn \tl_if_eq:nnT {nx}
\ExplSyntaxOff
\begin{document}
\SetAcceptableValues{AA,BB,CC}
\ExamineFile{FileA}{FileB}
\DTLloadrawdb[noheader,keys={Problem}]{MyDB}{FileB.tex}%
\DTLdisplaydb{MyDB}
\end{document}
정규식을 사용하는 또 다른 솔루션입니다. \XXX
댓글에서 요청하신 대로 접두사로 추가했습니다 .
\begin{filecontents*}{FileA.tex}
\XXX={AA}
some other tex content
\XXX={YY}
\XXX={BB}
and some more tex content
\XXX={ZZ}
\XXX={CC}
\end{filecontents*}
\documentclass{article}
\usepackage{datatool,xparse,l3regex}
\newcommand{\XXX}{XXX} % just to print the database
\ExplSyntaxOn
\regex_new:N \g_grill_prefix_regex
%% Here you set the prefix
%% We specify \XXX, any number of spaces and =
\regex_gset:Nn \g_grill_prefix_regex { \c{XXX} \s*? = }
%%
\regex_new:N \l__grill_acceptable_regex
\seq_new:N \g_grill_acceptable_seq
\seq_new:N \l__grill_temp_seq
\ior_new:N \l_grill_input_stream
\iow_new:N \l_grill_output_stream
\NewDocumentCommand{\SetAcceptableValues}{m}
{
\seq_gset_split:Nnn \g_grill_acceptable_seq { , } { #1 }
}
\NewDocumentCommand{\ExamineFile}{mm}
{% #1 = input file, #2 = output file
\grill_examine_file:nn { #1 } { #2 }
}
\cs_new_protected:Npn \grill_examine_file:nn #1 #2
{
\ior_open:Nn \l_grill_input_stream { #1 }
\iow_open:Nn \l_grill_output_stream { #2 }
\ior_open:Nn \l_grill_input_stream { #1 }
\iow_open:Nn \l_grill_output_stream { #2 }
\regex_set:Nx \l__grill_acceptable_regex
{
\exp_not:n{\cB.}
(\seq_use:Nnnn \g_grill_acceptable_seq { | } { | } { | } )
\exp_not:n{\cE.}
}
\ior_map_inline:Nn \l_grill_input_stream
{ \__grill_lookup_line:n { ##1 } }
\iow_close:N \l_grill_output_stream
\ior_close:N \l_grill_input_stream
}
\cs_new_protected:Npn \__grill_lookup_line:n #1
{
%% Check if the prefix is present
\regex_match:NnT \g_grill_prefix_regex { #1 }
{
%% Check whether the value is not among the acceptable ones
\regex_match:NnF \l__grill_acceptable_regex { #1 }
{ \iow_now:Nn \l_grill_output_stream { #1 } }
}
}
\cs_generate_variant:Nn \regex_set:Nn { Nx }
\ExplSyntaxOff
\begin{document}
\SetAcceptableValues{AA,BB,CC}
\ExamineFile{FileA}{FileB}
\DTLloadrawdb[noheader,keys={Problem}]{MyDB}{FileB.tex}%
\DTLdisplaydb{MyDB}
\end{document}