In einem Unterverzeichnis habe ich über 70 tex-Dateien. Wie kann ich diese möglichst einfach, z.B. über eine Schleife, in ein LaTeX-Hauptdokument per input-Befehl einlesen? Ergänzung bzw. Konkretisierung: Die Anzahl der Dateien ist variabel; die Namen folgen leider keinem Schema (sie sind Namen von Personen).

gefragt 20 Sep '14, 14:35

Mossbrucker's gravatar image

Mossbrucker
5417
Akzeptiert: 100%

bearbeitet 21 Sep '14, 10:54

cis's gravatar image

cis
5.4k860169

multido, pgffor, was dir beliebt. Wichtig ist aber, dass die Dateien so benannt sind, dass sich das automatisieren lässt.

(20 Sep '14, 14:42) Johannes

Die Namen der Dateien sind leider Namen von Personen, also lässt sich das wohl über die Dateinamen nicht automatisieren.

(20 Sep '14, 14:48) Mossbrucker

Hab es nicht probiert, aber eine foreach-Schleife könnte gehen. Die Mühe, die Dateinamen einzutippen, wird man sich in allen Fällen machen müssen (sofern diese nicht sequentiell simpel sind).

(20 Sep '14, 14:52) cis

Hier mal eine klassische Handwerkslösung mit datatool:

0) Erstmal habe ich mir einen Ordner angelegt, mit Hilfsdateien alpha.tex, beta.tex, gamma.tex; sie sehen inhaltlich schlicht so aus:

Open in writeLaTeX
Das ist die Datei alpha.tex

1) Als erstes brauchen wir eine Liste Files.csv, welche die genannten Dateien auflistet.

1a) Mit dem Windows-Befehl

Open in writeLaTeX
dir /s /p *.tex

erhalten wir folgende Übersicht über unsere einzubindenden Dateien:

Open in writeLaTeX
 Datenträger in Laufwerk C: ist Boot
 Volumeseriennummer: 8A59-DE79

 Verzeichnis von C:\Test

20.09.2014  23:13                27 alpha.tex
20.09.2014  23:13                26 beta.tex
20.09.2014  23:13                29 gamma.tex
20.09.2014  23:49               682 main.tex
               4 Datei(en),            764 Bytes

     Anzahl der angezeigten Dateien:
               4 Datei(en),            764 Bytes
               0 Verzeichnis(se), 121.686.958.080 Bytes frei

1b) Für unsere Zwecke passen wir den DIR-Befehl noch an:

Open in writeLaTeX
dir /b *.tex >Files.csv

was ohne Weiteres die Liste (Files.csv)

Open in writeLaTeX
alpha.tex
beta.tex
gamma.tex
main.tex

liefert.

Hierzu eine Anmerkung:

  • Die evtl. vorhandene Hauptdatei main.tex wird mitgefunden; wir werden sie später in der datatool-Schleife ausschließen.

2) So, und jetzt können wir folgende Hauptdatei (main.tex) übersetzen:

Open in writeLaTeX
\documentclass{article}

\usepackage{datatool}

%\DTLsetseparator{ }
\DTLloaddb[
  noheader,
  keys={name}
  ]{myfiles}{Files.csv}

\begin{document}
\section*{Einbindung der Dateien:}

\DTLforeach*[\not\DTLiseq{\Name}{main.tex}] 
{myfiles}{\Name=name}{%% 
    \section{\Name}
    \input{\Name}
 }%%
\end{document}

alt text







Zusatz: Wir könnten auch auf die Idee kommen, die o.g. Schritte automatisch in einem Zug, und zwar dokumentintern, auszuführen.

Dazu können wir arara (Weiteres: hier) und die arara-Regel console.yaml von @Clemens verwenden.

Mit arara kompilieren wir dann das gleiche Dokument, mit ergänztem arara-Dokumentkopf:

Open in writeLaTeX
% arara: console: { command: 'cmd /c dir /b *.tex >Files.csv' }
% arara: pdflatex

\documentclass{article}

\usepackage{datatool}

%\DTLsetseparator{ }
\DTLloaddb[
  noheader,
  keys={name}
  ]{myfiles}{Files.csv}

\begin{document}
\section*{Einbindung der Dateien:}

\DTLforeach*[\not\DTLiseq{\Name}{main2.tex}] 
{myfiles}{\Name=name}{%% 
    \section{\Name}
    \input{\Name}
 }%%
\end{document}

Was die selbe Ausgabe wie in 2) liefert.

Permanenter link

beantwortet 20 Sep '14, 18:09

cis's gravatar image

cis
5.4k860169

bearbeitet 21 Sep '14, 06:40

So, AW überarbeitet - egtl. sehr simple alles - man sollte eben die richtige Liste erstellen ;)

(21 Sep '14, 05:55) cis

Perfekt für meine Bedürfnisse - Danke.

(21 Sep '14, 07:04) Mossbrucker

Es muß halt arara vorhanden sein, für die vollautomatische Lösung. Ich frage mal @PauloCereda, ob er die Konsolen-Regel in die neue arara-Version aufnehmen will.

(21 Sep '14, 07:07) cis

Hier eine vom Betriebssystem unabhängige Lösung:

Mit pythontex funktioniert es wie unten gezeigt mit Hilfe des Moduls os. Das Modul glob wäre noch eine Alternative.

Die einzubindenden tex-Dateien sollten in einem seperaten Verzeichnis (hier unterverzeichnis genannt) liegen.

Open in writeLaTeX
\documentclass{article}

\usepackage{pythontex}

\begin{document}

\begin{pycode}
import os

l = [f for f in os.listdir('./unterverzeichnis/') if f.endswith('.tex')]

for i in l:
    print(r'\input{',i,'}',sep='')
\end{pycode}

\end{document}

Der Pythoncode kann natürich noch beliebig erweitert und verfeinert werden, z.B. indem die einzubindenden Dateien nach einem bestimmten Algorithmus sortiert oder nachbearbeitet werden, etc.

Kompiliert werden muss das Ganze über

Open in writeLaTeX
latex hauptdatei.tex
pythontex.py hauptdatei.tex
latex hauptdatei.tex

Mit pdflatex geht's natürlich auch. Man beachte, dass Python3-Code verwendet wurde. Mit Python2-Code kann man aber auch arbeiten.

Nebenbemerkung: Zu Testzwecken würde ich das aktuelle pythontex-Paket erstmal von CTAN laden und ins Hauptverzeichnis des Dokuments entpacken, falls man es nicht über die TeX-Distribution installieren kann oder will. pythontex kann man dann über python pythontex.py hauptdatei.tex laufen lassen, falls der Pfad zu python gesetzt ist. Ansonsten muss dieser manuell mitangegeben werden.

Permanenter link

beantwortet 20 Sep '14, 15:45

feynman's gravatar image

feynman
9671431

bearbeitet 21 Sep '14, 07:51

Danke für den Vorschlag. "Leider" habe ich einen Windowsrechner, kein Python installiert, unter MiKTeX auch kein pythontex installiert (die letzten beiden Dinge wären allerdings eher kein wirkliches Problem). So hoffe ich noch ein wenig auf eine andere Lösung, bevor ich die 75 Dateinamen einzeln eintippen muss.

(20 Sep '14, 17:10) Mossbrucker

Ich habe nochmal ein wenig was zum modul glob nachgelesen und wenn ich das richtig verstanden habe sollte es wie oben gezeigt doch unter Windows funktionieren. Vielleicht kann das ja mal jemand mit Windowsrechner testen. Wie gesagt, falls nicht, findet sich mit Sicherheit ein anderes Pythonmodul zur Realisierung, die Lösung bliebe aber ähnlich..

(21 Sep '14, 03:56) feynman

Es müsste eigentlich auch möglich sein, die Aufgabe mit lualatex zu lösen, da ja lua-Befehle im tex-Dokument ausgeführt werden können. lua ist ja wie python auch eine eigenständige Programmier-/Skriptsprache.

(21 Sep '14, 11:08) feynman

Bei Verwendung von lualatex kann man unabhängig vom Betriebssystem die darin enthaltene lfs-Erweiterung nutzen, um sämtliche Dateien eines Verzeichnisses zu ermitteln:

Open in writeLaTeX
\documentclass{article}

\usepackage{luacode}

\begin{document}
\section*{Einbindung der Dateien:}

\begin{luacode}
  fileend=".tex"
  searchdir="dir" -- Hier statt dir das gewünschte Verzeichnis angeben.
  for file in lfs.dir( searchdir ) do
    -- file ist jetzt die aktuelle Datei, von der wir noch testen müssen
    -- ob sie die Endung .tex hat
    if string.sub( file, #file-3 ) == fileend then
      print ( "Lese: " .. file )
      tex.print( "\\section*{" .. file .. "}\\input{".. searchdir .. "/" .. file .. "}" )
    end
  end
\end{luacode}
\end{document}

Dafür benötigt man nicht einmal --shell-escape. Wenn die LaTeX-Aktion, die man für die gefundene Datei anwenden möchte, etwas aufwendiger ist, lohnt es sich, ein Makro dafür zu definieren:

Open in writeLaTeX
\documentclass{article}

\usepackage{luacode}

\newcommand*{\doforfileindir}[2]{%
  \typeout{Lese Datei: `#1' in Verzeichnis `#2'}
  \section*{#1}
  \input{#2/#1}
}

\begin{document}
\section*{Einbindung der Dateien:}

\begin{luacode}
  local fileend=".tex"
  local searchdir="dir" -- Hier statt dir das gewünschte Verzeichnis angeben.
  for file in lfs.dir( searchdir ) do
    -- file ist jetzt die aktuelle Datei, von der wir noch testen müssen
    -- ob sie die Endung .tex hat
    if string.sub( file, #file-3 ) == fileend then
      tex.print( "\\doforfileindir{" .. file .."}{".. searchdir .. "}" )
    end
  end
\end{luacode}
\end{document}

Und natürlich kann man auch gleich ein Makro für das ganze definieren:

Open in writeLaTeX
\documentclass{article}

\usepackage{luacode}

\newcommand*{\doforfileindir}[2]{%
  \typeout{Lese Datei: `#1' in Verzeichnis `#2'}
  \section*{#1}
  \input{#2/#1}
}

\newcommand*{\inputalltexfilesin}[1]{%
  \luaexec{
    local fileend=".tex"
    local searchdir="#1"
    for file in lfs.dir( searchdir ) do
      % file ist jetzt die aktuelle Datei, von der wir noch testen müssen
      % ob sie die Endung .tex hat
      if string.sub( file, \#file-3 ) == fileend then
        tex.print( "\\doforfileindir{".. file.. "}{".. searchdir .. "}" )
      end
    end
  }
}

\begin{document}
\section*{Einbindung der Dateien:}
\inputalltexfilesin{dir}% Das Argument ist das Verzeichnis, das durchsucht wird.

\end{document}

Näheres zur Syntax von luacode und \luadirect ist der Anleitung zum Paket luacode zu entnehmen. Daraus erklärt sich dann auch, warum ich einmal Lua-Kommentare und einmal TeX-Kommentare verwende. Näheres zu Lua selbst findet man in der Lua-Dokumentation und zu LuaTeX in der Referenz-Anleitung.

Es sei noch darauf hingewiesen, dass im angegebenen Verzeichnis dir wie bei TeX üblich auch unter Windows / an Stelle von \\ zur Trennung zwischen Unterverzeichnisnamen zu verwenden ist.

Permanenter link

beantwortet 22 Sep '14, 04:18

Ijon%20Tichy's gravatar image

Ijon Tichy
4.4k618

bearbeitet 22 Sep '14, 05:51

Sehr schöne Lösung. Gerade habe ich nur noch ein Problem mit "ß" in den Namen, die Umlaute kommen richtig, aber das "Problem" werde ich später angehen, wenn ich ein wenig mehr Zeit habe.

(23 Sep '14, 12:58) Mossbrucker

Unter Linux: cat *.tex>sammel.tex

Unter Windows vermutlich mit type,echo oder copy anstatt cat.

Einfach ausprobieren.

Dann input sammel.tex

Permanenter link

beantwortet 20 Sep '14, 17:32

ctansearch's gravatar image

ctansearch
(inaktiv)

bearbeitet 21 Sep '14, 15:43

Danke, das funktioniert. Da sich die Anzahl und Inhalte der einzelnen tex-Dateien regelmässig ändern (es sind Abwesenheitsblätter), wäre eine Lösung direkt im Hauptdokument - so ähnlich wie in der ersten Antwort - "schöner". Aber die Lösung über type ist auf jeden Fall sehr viel besser als alles von Hand eintippen.

(20 Sep '14, 18:05) Mossbrucker

>> schreibt hinten dran, die Einträge würden sich vervielfachen. Wäre nicht > besser?

(21 Sep '14, 09:27) Johannes

Ich habe auch nur > verwendet.

(21 Sep '14, 10:10) Mossbrucker
Deine Antwort auf die Frage (nicht auf andere Antworten)
Knebel-Vorschau

Folge dieser Frage

Per E-Mail:

Wenn Du Dich anmeldest, kannst Du Updates hier abonnieren

Per RSS:

Antworten

Antworten und Kommentare

Aktuelle Buch-Infos

LaTeX Cookbook

LaTeX Beginners Guide

Limitierter Rabatt ebook
50% Coupon code tDRet6Y

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs füge einfach zwei Leerzeichen an die Stelle ein, an der die neue Zeile sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Zugeordnete Themen:

×27
×9
×3
×2

Frage gestellt: 20 Sep '14, 14:35

Frage wurde angeschaut: 2,818 Mal

Zuletzt aktualisiert: 23 Sep '14, 12:58