Bash

將 bash 數組複製到名稱由另一個變數保存的變數

  • March 1, 2020

有很多類似的問題,但我不明白任何答案作為以下問題的解決方案:

我想創建一個包含兩個參數的 bash 函式,第一個是變數名,第二個是搜尋字元串(用於文件搜尋)。

結果,我希望變數名包含找到的文件的數組。

我有一個包含以下文件的目錄:

  • 一個.jpg
  • b.tif
  • c.jpg

函式定義為:

search-files--fill-array()
{
   local variable_name="${1}"
   declare -a eval ${variable_name}

   local search_string="${2}"
   echo "${search_string}"

   local nullglob_setting=$(shopt -p nullglob)
   shopt -s nullglob
   found_files=(${search_string})
   eval "${nullglob_setting}"

   eval ${variable_name}=(${found_files[@]})
}

但最後一行導致語法錯誤。它應該將數組分配給作為函式第一個參數呈現的變數,因此呼叫該函式:

search-files--fill-array my_variable_a "*.jpg"

所以想要的結果應該是

echo "${my_variable_a[@]}"

將兩個文件“a.jpg”和“c.jpg”顯示為一個數組,即

echo "${#my_variable_a[@]}"

應產生“2”。

如果它不必是一個數組,解決方案是使用以下最後一行:

eval ${variable_name}=\${found_files}

在沒有任何成功的情況下,我還嘗試使用 while 循環從舊數組中形成新數組,但這也不起作用。

eval ${variable_name}="\${found_files[@]}"

生成my_variable_a包含字元串但不包含數組的內容。

背景

也許我的方法是完全錯誤的。

為了清楚起見:我想用一個數組填充一些變數,每個變數都包含通過 globbing 找到的文件的文件名(對於不同的搜尋“字元串”總是以相同的方式)。我只希望文件,不考慮子目錄,我必須確定,結果總是可靠地排序。)

我想避免冗餘程式碼。

shopt部分是必要的,以確保,如果目前目錄中不存在文件,則數組填充零條目,而沒有 nullglob,則將有一個具有搜尋“字元串”內容的條目。

解決方案

正如比利叔叔建議的那樣,我可以declare -n var在這裡使用。

工作功能:

search-files--fill-array()
{
   declare -n function=$1
   local shopt_setting=$BASHOPTS
   shopt -s nullglob
   function=($2)
   [[ :$shopt_setting: = *:nullglob:* ]] || shopt -u nullglob
}

他提出的重置nullglob導致該功能不再包含的處理eval。您可以閱讀例如這個 stackexchange 文章來了解,為什麼避免eval值得考慮。

使用變數引用:

search-files--fill-array()
{
 typeset -n a=$1
 local s=$BASHOPTS
 shopt -s nullglob
 a=($2)
 [[ :$s: = *:nullglob:* ]] || shopt -u nullglob
}

prompt> touch foo.txt bar.txt
prompt> search-files--fill-array foo '*.txt'
prompt> typeset -p foo
declare -a foo=([0]="bar.txt" [1]="foo.txt")

help declare了解更多詳情(declare是 的同義詞typeset)。


declare -a eval ${variable_name}

這將聲明函式本地的兩個數組,一個命名eval,另一個命名為${variable_name}. 無論你為它們分配什麼,它都會在函式返回後失去。用於declare -g使它們全域化。

eval ${variable_name}=(${found_files[@]})=> 語法錯誤

echo foo=(bar)=> 語法錯誤相同。(是一個元字元,它不能在任何地方使用,但只能在命令的開頭(例如 after ;&&等)或作為分配給數組時使用的特殊語法的一部分。

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