2

Background:

I need to perform a conditional branch based on the first three characters of a file. I found a rather simple solution (on a Unix system, or PC with cygwin installed):

head -1 <file-name> | grep '^<string>'

which returns an empty string for the case where there is no match. My first thought was to write this content to a temporary file and then read that file in, but found an ingenious solution by egreg at Write18: capturing shell (script) output as command/variable? which allows you to capture the output directly into a TeX macro.

TeX Issue:

So, I have managed to get this mostly working. The one detail that does not work is that I need to pass in \FBFileNameWithPath to the \edef\TempResult. The code below is hard coded to only test the file A.tex. If I replace A.tex with \FBFileNameWithPath then pfdlatex just hangs. So with this file name hard coded I get:

enter image description here

The desired output is

enter image description here

Code:

\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 Answer 1

2

The following code does what you want, I believe.

\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}

In the first case I get

\def\ShellOutput{XY: ad nasdf s}

while in the second the result is

\def\ShellOutput{}

(just add \show\TempResult before the final \TempResult to see it).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .