如何正確地將輸入文件名送出到 find exec 中?
我想創建單個 LaTeX 源的兩個 pdf 輸出文件。
一個輸出文件是公開的,而另一個(包含更多資訊)變為私有。
我使用了一個make文件,它使用find來grep目錄中的tex文件。這是一個簡單的解決方案,因為這樣我可以在許多項目中重複使用 makefile 而無需修改其內容。
這是makefile的重要部分。
all: # This creates the public output file find -name *.tex -exec sh -c 'pdflatex {}' \;
現在我想再添加一行來創建私有輸出文件。它應該看起來像這樣:
all: # This creates the public output file find -name *.tex -exec sh -c 'pdflatex {}' \; # This creates the private output file find -name *.tex -exec sh -c 'pdflatex --jobname=ABC '\def\privatflag{}\input{XYZ}' {}' \;
對於 ABC,我尋找一種解決方案來指定預設 filname 但帶有前綴。
對於 XYZ,我尋找一種解決方案來在此處傳遞輸入文件名。
我認為內引號的使用在這裡也不正確。
更新 1:也許我可以用更簡單的方式來解釋這個問題。
此命令在命令 shell 中工作:
pdflatex --jobname=outputfile '\def\privatflag{}\input{inputfile.tex}'
但我正在尋找一種使用它的解決方案,
find -name *.tex -exec
這樣我就不需要指定輸入文件名 inputfile.tex。另外我尋找一種我不需要指定的方式
--jobname=outputfile
。它應該與帶有附加前綴的輸入文件名匹配。更新 2:感謝muru和Stéphane Chazelas,問題得到解決。
現在這是 makefile 的重要部分
all: # This creates the public output file find -name *.tex -exec sh -c 'pdflatex {}' \; # This creates the private output file find . -name '*.tex' -execdir sh -c 'pdflatex --jobname=privat_"$${1##*/}" "\def\privatflag{""}\input{$${1##*/}}"' {}-job {} \;
從您的範例中,我認為您需要的是:
find . -name '*.tex' -execdir sh -c 'pdflatex --jobname=foo"${1##*/}" "\def\privatflag{""}\input{${1##*/}}"' {}-job {} \;
分解它:
-execdir
在找到文件的目錄中執行命令。${1##*/}
從 . 給出的參數中去除路徑find
。""
in{}
是為了防止find
替換{}
為匹配的路徑。
sh -c
需要處理 find 給出的路徑並僅提取文件名。
由於您已經在使用 Makefile,因此您可以用
find
make 自己的機制替換您的文件來處理文件,假設您的.tex
文件位於目前目錄中的簡單情況。例如,這個 makefile 可能就足夠了:ALLTEX = $(wildcard *.tex) ALLPDF = $(ALLTEX:.tex=.pdf) $(ALLTEX:.tex=.internal.pdf) %.pdf: %.tex pdflatex $< %.internal.pdf: %.tex pdflatex --jobname=$@ '\def\privatflag{}\input{$<}' all: $(ALLPDF)
變數 ALLTEX 保存所有輸入文件的名稱,ALLPDF 通過用另一個後綴一次又一次地替換後綴
.tex
來轉換這些名稱,接下來的 2 行設置了一個規則,說明如何從 tex 文件生成 pdf 文件,接下來的 2 行設置了另一個規則,說明如何生成另一個後綴。
$<
將被輸入文件和$@
輸出文件名替換。最後,真正的目標
all:
說這取決於想要的 pdf 文件。使用 make 規則的優點是,如果源 tex 文件沒有更改,則不會重建 pdf。