
同様の質問がたくさんありますが、次の問題に対する解決策では答えを理解できません。
2つのパラメータを使用するbash関数を作成したいと思います。 1つ目は変数名、2つ目は検索文字列(ファイル検索用)です。
そのため、変数名に見つかったファイルの配列を保存したいと思います。
次のファイルを含むディレクトリがあります。
- .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[@]}"
2つのファイル「a.jpg」と「c.jpg」を配列として表示します。つまり、
echo "${#my_variable_a[@]}"
結果は「2」でなければなりません。
配列である必要がない場合、解決策は次の最後の行を使用することです。
eval ${variable_name}=\${found_files}
私は成功せずにwhileループを使って古い配列から新しい配列を形成しようとしましたが、それもうまくいきませんでした。
eval ${variable_name}="\${found_files[@]}"
my_variable_a
文字列は含まれているが配列は含まれていない結果を生成します。
背景
たぶん私が完全に間違っているのかもしれません。
明確に言うと、ワイルドカードを介して見つかったファイルのファイル名をそれぞれ保持するいくつかの変数で配列を埋めたいと思います(常に他の検索「文字列」と同じ方法)。サブディレクトリ以外のファイルのみを予想し、結果が常に確実にソートされるようにする必要があります。 )
重複するコードを避けたいです。
このshopt
部分は、ファイルが現在のディレクトリにない場合は配列がゼロ項目で埋められ、nullglobがない場合は「文字列」で検索されたコンテンツを含む項目が1つあることを確認するために必要です。
解決策
〜のようにビリー叔父ここで使用できる提案です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
。たとえば、読むことができます。このスタック交換ポスト回避をeval
検討する価値がある理由を学びます。
答え1
変数参照を使用します。
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}
これにより、2つの配列が宣言されます。地元の関数の場合、1つは名前が付けられ、eval
もう1つはcontentで名前が付けられます${variable_name}
。割り当てられた値は、関数が返された後に失われます。declare -g
それらをグローバル化するために。
eval ${variable_name}=(${found_files[@]})
=>構文エラー
echo foo=(bar)
=>構文エラーと同じです。(
コマンドの先頭(後など)や配列に割り当てるときに使用される特別な構文の一部以外は、どこでも使用できないメタ文字;
です&&
。