通过 \@@input 指定文件名 shell 访问

通过 \@@input 指定文件名 shell 访问

背景:

我需要根据文件的前三个字符执行条件分支。我找到了一个相当简单的解决方案(在 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即可看到)。

相关内容