Bash

將文件中的非 bash 變數讀入 bash 腳本

  • May 29, 2015

我的 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"

引用自:https://unix.stackexchange.com/questions/116360