我目前正在撰寫一個 bash 腳本來修改我的 LaTeX 編譯的輸出,使其僅包含我在控制臺上找到的相關列印內容。由于我希望這個腳本非常徹底,我設定了不同的選項來同時切換不同的輸出過濾器,具體取決于通過編譯給出的資訊的性質(致命錯誤、警告、過度/不足 h/vbox.. .)。
對于那些可能不知道的人,我們通常需要連續執行幾次編譯才能獲得完整的 LaTeX 檔案,其中包含正確的標簽、頁碼、索引、目錄... 其他命令,如參考書目和詞匯bibtex表makeglossaries. 因此,我有一個回圈,如果遇到致命錯誤,則執行所有內容并停止,但如果它只是一個小警告,則應該繼續。
我的主要命令列是pdflatex通過反向grep查找錯誤行(從 開始!)傳遞輸出。像這樣,腳本只有在grep發現致命錯誤時才會停止。
: | pdflatex --halt-on-error $@ | { ! grep --color=auto '^!.*' -A200; }
但是當我激活任何其他過濾器時(例如,'*.full.*'對于過滿/欠滿行),我需要能夠繼續編譯才能識別它,因此非常有必要對其進行更正(嘿,有時,欠滿行并非如此丑陋的...)。
這意味著我的grep命令不能像第一行那樣反轉,并且我不能(或不知道如何)將其grep與不同的正則運算式一起使用。請注意,如果使用不同的grep,也應該從pdflatex輸出中讀取它,并且我不能直接在上面的代碼片段之后對其進行管道傳輸。
總而言之,它應該大致如下所示:
pdflatex --> grep for fatal errors --> if more filters, grep for those filters
--> pass to next step
我想出了幾個不能正常作業的嘗試:
這個只有當我想用警告編譯時才有效。只尋找錯誤是行不通的。
latex_compilation() {
: | pdflatex --halt-on-error $@ | tee >({ ! grep --color=auto '^!.*' -A200; }) >({ grep --color=auto "$warnings_filter" -A5 };) >/dev/null
}
latex_compilation() {
: | pdflatex --halt-on-error $@ | tee >({ ! grep --color=auto '^!.*' -A200; }) >/dev/null | ({ grep --color=auto "$warnings_filter" -A5 };)
}
甚至拼命
latex_compilation() {
: | pdflatex --halt-on-error $@ |
if [[ "$warnings_on" = true ]]; then
{ grep --color=auto "$warnings_filter" -A5 };
fi
{ ! grep --color=auto '^!.*' -A200; }
}
這個可以作業,但每個步驟使用 2 個編譯程序(對于一個大而復雜的檔案,您可以輕松地達到 7/8 個編譯步驟)。如果可能的話,應該避免。
latex_compilation() {
if [[ "$warnings_on" = true ]]; then
: | pdflatex --halt-on-error $@ | \
{ grep --color=auto "$warnings_filter" -A5 };
fi
: | pdflatex --halt-on-error $@ | \
{ ! grep --color=auto '^!.*' -A200; }
}
我花了幾個小時在網上尋找解決方案,但還沒有找到。我真的希望這足夠清楚,因為總結起來很亂,而且寫下來。如果需要清楚起見,您可以在此處找到相關代碼。
uj5u.com熱心網友回復:
這個可以作業,但使用 2 個編譯程序
所以讓我們使用一個。
latex_compilation() {
local tmp
tmp=$(pdflatext ... <&-)
if [[ "$warnings_on" = true ]]; then
grep --color=auto "$warnings_filter" -A5 <<<"$tmp"
fi
! grep --color=auto '^!.*' -A200 <<<"$tmp"
}
或者您可以通過決議輸出,在您選擇的程式語言中異步執行此操作。對于 Bash,請參見https://mywiki.wooledge.org/BashFAQ/001:
line_is_warning() { .... }
latex_compilation() {
local outputlines=0 failed
while IFS= read -r line; do
if "$warnings_on" && line_is_warning "$line"; do
outputlines=5 # will output 5 lines after
fi
if [[ "$line" =~ ^! ]]; then
failed=1
outputlines=200 # will output 200 lines after
fi
if ((outputlines != 0)); then
((outputlines--))
printf "%s\n" "$line"
fi
done < <(pdflatext ... <&-)
if ((failed)); then return 1; fi
}
但是 Bash 會非常慢。考慮使用 AWK 或 Python 或 Perl。
在線尋找解決方案
確切地說,您必須自己撰寫解決方案,以滿足您的特定要求。
只有當我想用警告編譯時,他的一個才有效。只尋找錯誤是行不通的。
>( ... )您可以在內部以及基本上在任何地方撰寫整個代碼塊。管道的退出狀態是最右邊命令的退出狀態(除了set -o pipefail)。將失敗的命令放在管道的最右邊。
latex_compilation() {
pdflatex --halt-on-error "$@" <&- |
tee >(
if "$warnings_on"; then
grep --color=auto "$warnings_filter" -A5
else
cat >/dev/null
fi
) |
! grep --color=auto '^!.*' -A200
}
uj5u.com熱心網友回復:
建議使用awk過濾模式。
在此處閱讀有關awk過濾模式的更多資訊。
使用awk您可以創建復雜的過濾模式邏輯:!=not、&&=and、||=or。
例如,如果您有 3 個過濾正則運算式模式:Pattern_1, Pattern_2, Pattern 3.
示例 1
您可以在以下命令中對所有 3 種模式進行組合過濾:
awk '/Pattern_1/ && /Pattern_2/ && /Pattern_3/ 1' scanned_file1 scanned_file2 ...
結果將僅列印與所有 3 個模式匹配的行。
示例 2
您可以在以下命令中對所有 3 個模式進行組合反向過濾:
awk '!/Pattern_1/ && !/Pattern_2/ && !/Pattern_3/ 1' scanned_file1 scanned_file2 ...
結果將是列印與 3 種模式中的任何一種都不匹配的行。
示例 3
您可以制作組合的逆過濾器Pattern_1并匹配Pattern_2或Pattern_3:
awk '!/Pattern_1/ && (/Pattern_2/ || /Pattern_3/)' scanned_file1 scanned_file2 ...
結果將是列印行不匹配Pattern_1但匹配Pattern_2or Pattern_3。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/439463.html
上一篇:匹配模式后拆分多行
下一篇:自動修復聲納規則
