2

異なる名前の 3 つの同様のファイルを異なる配列に読み込もうとしています。不要なコードを使用したくなかったので、配列名をパラメーターとして受け入れる関数を作成しようとしていますが、「コマンドが見つかりません」というエラーが発生しています。

hello.sh ファイル コード:

    #!/bin/bash
declare -a row_1
declare -a row_2
declare -a row_3


load_array()
{
ROW="$2"
let i=0
while read line; do
    for word in $line; do
    $ROW[$i]=$word        
((++i))
    done
done < $1
}

load_array $1 row_1
load_array $2 row_2
load_array $3 row_3

端末からこのファイルを次のように呼び出します。sh hello.sh 1.txt 2.txt 3.txt

私が得ているエラーのリスト:

hello.sh: line 13: row_1[0]=9: command not found
hello.sh: line 13: row_1[1]=15: command not found
hello.sh: line 13: row_1[2]=13: command not found
hello.sh: line 13: row_2[0]=12: command not found
hello.sh: line 13: row_2[1]=67: command not found
hello.sh: line 13: row_2[2]=63: command not found
hello.sh: line 13: row_3[0]=75: command not found
hello.sh: line 13: row_3[1]=54: command not found
hello.sh: line 13: row_3[2]=23: command not found
4

2 に答える 2

1

代入構文では、等号の左側は、変数名 (スカラーに代入する場合)、または変数名の後に角括弧で囲まれた単語 (配列要素に代入する場合) のいずれかでなければなりません。コードでは、$ROW[$i]=$wordこの構文と一致しません ($先頭に a があるため、割り当てである可能性はありません); それはたまたま文字を含む単語です=

bash では、declareビルトインを使用して、変数展開などの計算の結果である名前を持つ変数に割り当てることができます。直接代入の場合とは異なり、単語の分割とファイル名の展開を防ぐために、値の部分を二重引用符で囲む必要があることに注意してください$word-g関数で割り当てを行っていて、関数が戻った後も値を残したい場合は、オプションを渡します。

declare -g $ROW[$i]="$word"

を持たない古いバージョンの bash を実行している場合はdeclare -g、代わりに使用できますeval。これは、プレーンな sh で動的に名前が付けられた変数に割り当てるために使用する方法です。物事を適切に引用するように注意してください。ROWたとえばが の場合row_1、引数として渡される文字列は、(解析して実行するシェル コマンド) にするeval必要があります。row_1[$i]=$word

eval "$ROW[\$i]=\$word"
于 2014-11-20T20:47:50.387 に答える
1

したがって、最新の (bash 4.3+) 構文でこれを行う理想的な方法は次のとおりです。

load_array() {
  declare -n _load_array__row=$2
  declare -a _load_array__line
  _load_array__row=( )
  while read -r -a _load_array__line; do
    _load_array__row+=( "${_load_array__line[@]}" )
  done <"$1"
}

(変数名は、呼び出し元の関数との衝突の可能性を減らすために奇妙です。たとえば、ローカル変数を参照するため、ROWまたはという名前の変数にコンテンツをロードするように求められた場合、与えられた他の回答は問題になりますline目的地を説明する際にグローバルなものではなく)。


*bash 3.2 (Apple が出荷した古いリリース) と互換性のある同様のメカニズムは、内部ループに関連するパフォーマンスの低下とグロブ展開に関連するバグを回避します ( !を含む行に対する元のコードの動作を参照してください)。

load_array() {
  local -a _load_array__array=( )
  local -a _load_array__line
  while read -r -a _load_array__line; do
    _load_array__array+=( "${_load_array__line[@]}" )
  done <"$1"
  eval "$2=( \"\${_load_array__array[@]}\" )"
}
于 2014-11-21T01:41:25.103 に答える