Bash
將文件中的非 bash 變數讀入 bash 腳本
我的 bash 腳本需要從包含數百個變數的文本文件中讀取變數,其中大部分符合標準 bash 變數語法(例如,
VAR1=VALUE1
)。但是,這個文件中的幾行可能會出現問題,我希望找到一個簡單的解決方案來將它們讀入 bash。文件如下所示:
#comment VAR1=VALUE1 VAR_2=VALUE_2 ... VAR5=VALUE 5 (ASDF) VAR6=VALUE 6 #a comment VAR7=/path/with/slashes/and,commas VAR8=2.1 VAR9=a name with spaces VAR_10=true ... VAR_N=VALUE_N
關於文件結構的規則包括:
- 每行一個變數(帶值)
- 賦值 (=) 周圍沒有空格
- 變數名在第一列(除非它是註釋行)
- 註釋可以跟在值後面(# 之後)
- 這些值可以包括空格、括號、斜杠、逗號和其他字元
- 這些值可以是浮點數 (2.1)、整數、真/假或字元串。
- 字元串值不被引用,它們可以是一千個字元長或更長
- 變數名稱僅包含字母和下劃線 UPDATE:和 numbers。
大多數變數的類型只允許我將文件源到我的 bash 腳本中。但是這幾個有問題的問題決定了一個不同的解決方案。我不確定如何閱讀它們。
雖然您可以將此文件轉換為 shell 片段,但這很棘手。您需要確保正確引用所有 shell 特殊字元。
最簡單的方法是在值周圍加上單引號並將值內的單引號替換為
'\''
. 然後,您可以將結果放入臨時文件並獲取該文件。script=$(mktemp) sed <"config-file" >"$script" \ -e '/^[A-Z_a-z][A-Z_a-z]*=/ !d' \ -e s/\'/\'\\\\\'\'/g \ -e s/=/=\'/ -e s/\$/\'/
我建議直接在 shell 中進行解析。程式碼的複雜性大致相同,但有兩個主要好處:您避免了對臨時文件的需要,以及您意外引用錯誤並最終將行的一部分作為 shell 片段執行的風險 (類似
dangerous='$(run me)'
)。您還可以更好地驗證潛在錯誤。while IFS= read -r line; do line=${line%%#*} # strip comment (if any) case $line in *=*) var=${line%%=*} case $var in *[!A-Z_a-z]*) echo "Warning: invalid variable name $var ignored" >&2 continue;; esac if eval '[ -n "${'$var'+1}" ]'; then echo "Warning: variable $var already set, redefinition ignored" >&2 continue fi line=${line#*=} eval $var='"$line"' esac done <"config-file"