背景:
我需要根据文件的前三个字符执行条件分支。我找到了一个相当简单的解决方案(在 Unix 系统或安装了 cygwin 的 PC 上):
head -1 <file-name> | grep '^<string>'
如果没有匹配,则返回空字符串。我的第一个想法是将此内容写入临时文件,然后读取该文件,但发现了 egreg 的一个巧妙的解决方案Write18:捕获 shell(脚本)输出作为命令/变量?它允许您将输出直接捕获到 TeX 宏中。
TeX 问题:
所以,我设法得到了这个大多工作。一个不起作用的细节是我需要传递\FBFileNameWithPath
给\edef\TempResult
。下面的代码被硬编码为仅有的测试文件A.tex
。如果我用 替换,A.tex
则\FBFileNameWithPath
只会pfdlatex
挂起。因此,使用此文件名硬编码,我得到:
期望的输出是
代码:
\documentclass{article}
\usepackage{xstring}
%\usepackage{filecontents}% Commented so as to not overwrite any existing files
\begin{filecontents*}{A.txt}
XY: ad nasdf s
sgs sg sg sg
\end{filecontents*}
\begin{filecontents*}{B.txt}
ZZ: ad nasdf s
sgs sg sg sg
\end{filecontents*}
%% https://tex.stackexchange.com/questions/16790/write18-capturing-shell-script-output-as-command-variable
\newcommand*{\FBFileNameWithPath}{}%
\begingroup\makeatletter\endlinechar=\m@ne\everyeof{\noexpand}
\edef\TempResult{\endgroup\def\noexpand\ShellOutput{\@@input|"head -1 A.txt | grep '^XY:'" }}\TempResult%
\begin{document}
% Should be "matched" as A.txt starts with XY:
\xdef\FBFileNameWithPath{./A.txt}
A.txt: \IfStrEq{\ShellOutput}{}{Not matched}{matched.}%
% Should be "Not matched" as B.txt does NOT start with XY:
\xdef\FBFileNameWithPath{./B.txt}
B.txt: \IfStrEq{\ShellOutput}{}{Not matched}{matched.}%
\end{document}
答案1
我相信下面的代码可以实现您想要的功能。
\documentclass{article}
\usepackage{xstring}
\begin{filecontents*}{A.txt}
XY: ad nasdf s
sgs sg sg sg
\end{filecontents*}
\begin{filecontents*}{B.txt}
ZZ: ad nasdf s
sgs sg sg sg
\end{filecontents*}
\makeatletter
\newcommand\GetShellOutput{%
\begingroup\endlinechar=\m@ne\everyeof{\noexpand}%
\edef\TempResult{\endgroup
\def\noexpand\ShellOutput{%
\@@input|"head -1 \FBFileNameWithPath | grep '^XY:'" }}%
\TempResult}
\makeatother
\newcommand*{\FBFileNameWithPath}{}
\begin{document}
% Should be "matched" as A.txt starts with XY:
\renewcommand\FBFileNameWithPath{./A.txt}
\GetShellOutput
A.txt: \IfStrEq{\ShellOutput}{}{Not matched}{matched.}%
% Should be "Not matched" as B.txt does NOT start with XY:
\renewcommand\FBFileNameWithPath{./B.txt}
\GetShellOutput
B.txt: \IfStrEq{\ShellOutput}{}{Not matched}{matched.}%
\end{document}
在第一种情况下我得到
\def\ShellOutput{XY: ad nasdf s}
而第二个结果是
\def\ShellOutput{}
(只需\show\TempResult
在最后添加\TempResult
即可看到)。