다음 스크립트는 .tex
디렉토리에서 접미사가 있는 파일(예: TeX 파일)을 검색하고 \RequireLuaTeX
해당 디렉토리에서 문자열(예: LuaTeX 파일)을 찾은 다음 결과를 기반으로 Bash 배열을 만듭니다.
latexmk
그런 다음 배열의 파일에 대해 명령을 실행합니다.
배열로 선언될 수 있는 사용자 정의 파일 목록을 이 배열에서 제외하고 싶습니다.
excludedfiles=(foo.tex bar.tex baz.tex)
깔끔한 접근 방식에 대한 조언을 구하고자 글을 씁니다.
나는 모든 것을 배열에 넣는 방법을 정말 좋아합니다. 우선, 명령을 실행하기 전에 파일 목록을 쉽게 나열할 수 있습니다. 하지만 나는 다른 접근 방식도 고려해 볼 의향이 있습니다.
#!/bin/bash
## Get LuaTeX filenames
mapfile -t -d "" filenames < <(grep -Z -rL "\RequireLuaTeX" *.tex)
## Run `latexmk` on PDFTeX files.
for filename in "${filenames[@]}"
do
base="${filename%.*}"
rm -f "$base".pdf
latexmk -pdf -shell-escape -interaction=nonstopmode "$base".tex
done
배경 및 설명:
TeX 사용자는 내 질문에 혼란스러울 수 있습니다. 그래서 여기서는 제가 하려는 일과 질문을 어떻게 잘못 썼는지 설명하겠습니다. 변경하면 기존 답변이 무효화되고 혼란이 생길 수 있으므로 변경하지 않겠습니다.
LaTeX 파일 세트가 있습니다. 이전 버전은 PDFLaTeX를 사용합니다. 최신 버전은 대부분 PDFLaTeX를 사용합니다. PDFLaTeX에 관한 질문입니다. 내가 스크립트에서 하고 싶은 것은
a) PDFLaTeX 파일 목록을 만듭니다. 내 LuaLaTeX 파일에는 "\RequireLuaTeX" 문자열이 포함되어 있습니다. 따라서 이 문자열을 포함하지 않는 파일은 PDFLaTeX 파일입니다.
그래서 "\RequireLuaTeX" 문자열을 포함하지 않는 LaTeX 파일 목록을 만들려고 합니다.
b) 를 사용하여 PDFLaTeX를 실행합니다 latexmk
.
내 질문에 다음과 같은 오류가 있습니다. 나는 썼다:
다음 스크립트는
.tex
디렉토리에서 접미사가 있는 파일(예: TeX 파일)을 검색하고\RequireLuaTeX
해당 디렉토리에서 문자열(예: LuaTeX 파일)을 찾은 다음 결과를 기반으로 Bash 배열을 만듭니다.
사실 저는 이 문자열을 포함하지 않는 파일을 원합니다. 왜냐하면 위에서 언급한 것처럼 이러한 파일은 제 PDFLaTeX 파일에 해당하기 때문입니다.
답변1
-L
패턴과 일치하지 않는 Grep 파일 목록을 표시합니다. 당신은 대신 원합니다 -l
. 또한 Grep은 단일 백슬래시와 일치하도록 이중 백슬래시를 확인해야 합니다.
이제 Bash를 사용하고 있으므로 몇 가지 유용한 구성을 마스터해 보겠습니다.
#!/bin/bash -
shopt -s globstar extglob
mapfile -t -d "" filenames < <(grep -Zl '\\RequireLuaTeX' ./**/!(foo|bar|baz).tex)
rm -f "${filenames[@]/%.tex/.pdf}"
latexmk -pdf -shell-escape -interaction=nonstopmode "${filenames[@]}"
**/!(foo|bar|baz).tex
현재 디렉토리 트리에서 or 로 끝나지만.tex
기본 이름이 아닌 모든 파일로 확장됩니다foo.tex
. 둘 다bar.tex
baz.tex
globstar
그리고extglob
이 작업에 필요합니다."${filenames[@]/%.tex/.pdf}"
배열의 모든 요소로 확장되어 각 요소를 대체합니다.뒤따라.tex
통과.pdf
.
Latexmk는 여러 파일을 매개변수로 제공할 수 있으므로 for 루프를 건너뛸 수 있습니다.
답변2
를 사용하면 매개변수 확장 플래그를 사용하여 이스케이프된 전역 문자가 있는 요소를 연결하여 zsh
배열을 해당 요소와 일치하는 패턴으로 변환 할 수 있습니다.|
j[|]
b
#! /bin/zsh -
set -o extendedglob
excluded_file_names=(foo.tex bar.tex baz.tex)
excluded_file_names_pattern="(${(j[|])${(@b)excluded_file_names}})"
# here using the ~ extendedglob operator to apply the exclusion
tex_files=(
./**/(*.tex~$~excluded_file_names_pattern)
)
files=(
${(0)"$(grep -lZF '\RequireLuaTeX' $tex_files)"}
)
rm -f ${files/%tex/pdf}
latexmk -pdf -shell-escape -interaction=nonstopmode $files
아니면 당신은 사용할 수 있습니다e
글로벌 예선t
모든 파일 경로가 배열에 있는지 확인하십시오 .
#! /bin/zsh -
excluded_file_names=(foo.tex bar.tex baz.tex)
tex_files=(
./**/*.tex(^e['(($excluded_file_names[(Ie)$REPLY:t]))'])
)
files=(
${(0)"$(grep -lZF '\RequireLuaTeX' $tex_files)"}
)
rm -f ${files/%tex/pdf}
latexmk -pdf -shell-escape -interaction=nonstopmode $files
답변3
이런 종류의 문제를 해결하는 방법은 검색 없이 즉석 조회를 통해 파일 이름/패턴 목록을 해시로 변환하는 것입니다. ( 은패턴excludedFiles
같은와z*.tex
z*.tex
excludedFiles
# User configurable list of files and patterns
excludedFiles=(foo.tex bar.tex baz.tex z*.tex)
# Convert the list into a hash
declare -A excludedHash
for excludedFile in "${excludedFiles[@]}"
do
[[ -e "$excludedFile" ]] && excludedHash[$excludedFile]=yes
done
# Processing
for filename in "${filenames[@]}"
do
[[ -n "${excludedHash[$filename]}" ]] && continue # Skip if filename is in hash
base="${filename%.*}"
rm -f "$base".pdf
latexmk -pdf -shell-escape -interaction=nonstopmode "$base".tex
done
답변4
배열 없이 간단한 for 루프를 사용하는 것이 좋습니다.
excludedfiles="foo.tex|bar.tex|baz.tex"
for i in $(ls *.tex | egrep -vx ${excludedfiles});do
filename=$(grep -H "\\RequireLuaTeX" $i | awk -F ':' '{print $1}')
base=${filename%.*}
if [[ "$base" == "" ]];then continue; fi
rm -f "$base".pdf
latexmk -pdf -shell-escape -interaction=nonstopmode "$base".tex
done
할 수 있는 작업:
- 파일 찾기
.tex
- 지정된 파일 필터링(egrep)
- 텍스트 검색은 패턴을 지정합니다
\RequireLuaTeX
(검색 시 "\\"에는 \가 포함됨). - 빈 변수를 확인
filename
하고 비어 있으면 다음 변수로 이동합니다(grep이 일치하는 항목을 찾지 못한 경우 발생함). - 주어진 명령을 사용하여 완료
rm
Final 및 command 없이 스크립트를 테스트 실행하고 latex
"에코"하여 출력을 확인하는 것이 좋습니다 "$base"
. (모든 솔루션에 대해) 파일 이름의 공백 문제를 상상할 수 있습니다.
...
if [[ "$base" == "" ]];then continue; fi
echo $base
done
원하는 경우 모든 검색 패턴을 추출하여 더 나은 조정과 손쉬운 처리를 위해 변수에 넣을 수 있습니다.