Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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

%% http://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}
share|improve this question

1 Answer 1

up vote 2 down vote accepted

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).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.