我有几个.txt
或.dat
文件,其名称的形式为:dn-ddmmyyyy.txt
。例如:
d0-01021989.txt
d1-21021989.txt
d2-15021994.txt
d3-12121996.txt
d4-14032014.txt
d5-22022035.txt
...many more...
\include
包含所有文件而无需手动逐个使用的最佳方法是什么?
有没有办法为每个文档创建一个标题(如章节标题),如“文档 N”,并提取文件名中的数字(即日期)并将其放入标题中?
有没有办法仅使用 TeX 来实现这一点?
答案1
我不知道是否有仅限 TeX 的解决方案(但我可以想象这lualatex
很方便),但我通常会这样做:
1)使用类似的命令dir /b *.tex > allFiles.txt?
获取所有 TeX 文件的文件。(/b
除了文件名之外,隐藏所有内容)
2)打开 Excel,粘贴内容allFiles.txt
并使用字符串连接来构建包含命令。
对于一次性来说,这是最有效的解决方案。如果我需要定期更新 TeX 文件,我会编写一个简短的 Python/Bash/Batch 文件。
编辑:
lualatex
我在其中一个答案中找到了通过 Lua 调用包含的一些合适的代码这里并能够对其进行一些调整。它\write18
也使用,因此必须与一起使用--shell-escape
。我非常确定仅使用 Lua 的解决方案是可能的,但这显然超出了我的 Lua 知识范围。
%!TEX TS-program = LuaLaTeX
\documentclass[12pt,ngerman]{scrartcl}
\usepackage{luacode}
\begin{document}
Some text before the Lua call.
\begin{luacode}
function scandir(directory)
local i, t, popen = 0, {}, io.popen
for filename in popen('dir "'.. directory .. '" /b d*.tex'):lines() do
i = i + 1
t[i] = filename
tex.print('\\input{includes/' .. filename .. '} from ' .. filename ..'\\clearpage')
end
return t
end
scandir("C:/Users/Uwe/LuaLula/includes/")
\end{luacode}
\end{document}
答案2
此解决方案仅适用于 Microsoft Windows 用户。对于 Linux、MAC、Unix 用户,您必须调整批处理相关部分。对此造成的不便深表歉意,感谢您的合作。
下面这段代码其实也是几十年前准备好的此处(点击). 使用 进行编译pdflatex -shell-escape filename
. 确保
- 要包含的输入文件放在子目录中
Sub-Dir
。 - 路径中不允许有空格(以简化代码)。
通用最小工作示例
% filename.tex
\documentclass[preview,border=12pt,12pt,varwidth]{standalone}
\usepackage{filecontents}
\begin{filecontents*}{batch.txt}
rem batch.bat
echo off
rem %1 path (relative to the main input file) to the files to be iterated
rem %2 output file name
rem remaining args represent the extension of file to be iterated
set curdir=%CD%
cd "%~1"
shift
rem output must be enclosed with "" to allow spaces in the path
set output="%curdir%\%~1.list"
if exist %output% del %output%
copy nul %output%
shift
:loop
if "%~1"=="" goto :eof
dir /b *.%~1 >> %output%
shift
goto :loop
\end{filecontents*}
\begin{filecontents*}{oh-my-ghost.tex}
No body no body but you!
\[
E\not = mc^2
\]
\end{filecontents*}
\begin{filecontents*}{hahaha.tex}
PSTricks is fun!
\[
pV = nRT
\]
\end{filecontents*}
\immediate\write18{%
del batch.bat &&
rename batch.txt batch.bat &&
move oh-my-ghost.tex Sub-Dir/oh-my-ghost.tex &&
move hahaha.tex Sub-Dir/hahaha.tex
}
\newread\reader
\newcount\TotalFiles
\makeatletter
\newcommand\IterateInputFiles[2][tex]{%
% #1: directory path with a trailing /
% #2: a list of file extensions: tex
\immediate\write18{batch "#2" \jobname\space #1}
\openin\reader=\jobname.list\relax
\loop
\read\reader to \filename
\unless\ifeof\reader
\filename@parse{\filename}
\section{\filename@base}% change to \chapter if you want
\include{"#2\filename@base"}
\advance\TotalFiles1\relax
\repeat
\closein\reader
}
\makeatother
\begin{document}
\IterateInputFiles{Sub-Dir/}
\section{Summary}
There is(are) \the\TotalFiles\ file(s) in total.
\end{document}
输出
下面的输出证明我没有说谎。
多平台版本
% filename.tex
\documentclass[preview,border=12pt,12pt,varwidth]{standalone}
\newif\ifDOS
%\DOStrue
\DOSfalse
\usepackage{filecontents}
\ifDOS
\begin{filecontents*}{batch.txt}
rem batch.bat
echo off
rem %1 path (relative to the main input file) to the files to be iterated
rem %2 output file name
rem remaining args represent the extension of file to be iterated
set curdir=%CD%
cd "%~1"
shift
rem output must be enclosed with "" to allow spaces in the path
set output="%curdir%\%~1.list"
if exist %output% del %output%
copy nul %output%
shift
:loop
if "%~1"=="" goto :eof
dir /b *.%~1 >> %output%
shift
goto :loop
\end{filecontents*}
\else
\begin{filecontents*}{batch.txt}
#!/bin/bash
# bash batch.sh Sub-Dir output tex
# $1 path (relative to the main input file) to the files to be iterated
# $2 output file name
# remaining args represent the extension of file to be iterated
output="$2.list"
if [ -e "$output" ]; then
rm "$output"
fi
for ext in ${@:3}; do
ls "$1"/*."$ext" >> "$output"
done
# $ (to squelch bad syntax highlighting in my editor)
\end{filecontents*}
\fi
\begin{filecontents*}{oh-my-ghost.tex}
No body no body but you!
\[
E\not = mc^2
\]
\end{filecontents*}
\begin{filecontents*}{hahaha.tex}
PSTricks is fun!
\[
pV = nRT
\]
\end{filecontents*}
\ifDOS
\immediate\write18{%
del batch.bat &&
rename batch.txt batch.bat &&
move oh-my-ghost.tex Sub-Dir/oh-my-ghost.tex &&
move hahaha.tex Sub-Dir/hahaha.tex
}
\else
\immediate\write18{%
mv batch.txt batch.sh &&
mkdir -p Sub-Dir &&
mv oh-my-ghost.tex hahaha.tex Sub-Dir/
}
\fi
\newread\reader
\newcount\TotalFiles
\makeatletter
\newcommand\IterateInputFiles[2][tex]{%
% #1: directory path with a trailing /
% #2: a list of file extensions: tex
\ifDOS
\immediate\write18{batch "#2" \jobname\space #1}
\else
\immediate\write18{bash batch.sh "#2" \jobname\space #1}
\fi
\openin\reader=\jobname.list\relax
\let\filename\relax
\loop
\read\reader to \filename
\typeout{<<< here again}
\unless\ifeof\reader
\filename@parse{\filename}
\section{\filename@base}% change to \chapter if you want
\include{"#2\filename@base"}
\advance\TotalFiles1\relax
\repeat
\closein\reader
}
\makeatother
\begin{document}
\IterateInputFiles{Sub-Dir/}
\section{Summary}
There is(are) \the\TotalFiles\ file(s) in total.
\end{document}