Bashで$ {array [*]}に変数を使用する方法? -- arrays フィールド と bash フィールド と indexing フィールド 関連 問題

How to use a variable to index ${array[*]} in bash?












5
vote

問題

日本語

まず最初に私の英語が良くないので申し訳ありません。 変数を使用して、アレイ内の要素を索引付けしたり、同じ変数を使用してすべての要素を索引付けします。例えば:

<事前> <コード> ... var1="1" var2="*" array=(one two three for five) for elem in ${array[$var1]} do echo $elem done

var1 を使用して でインデックスを索引付けするときは正しく機能しますが、を使用している場合var2 が正しく機能しません、私はこのエラーを得ます:

<事前> <コード> ./ed.sh line XXX *: syntax error: operand expected (error token is "*")

エラーが*ワイルドカードの拡大と関連していることを確信していますが、この問題を解決するのに役立つ答えが見つかりませんでした。だから、どうすればいいですか?

英語

First of all sorry because my english may be not good. I want to use a variable to index an element in an array or use the same variable to index all the elements. For example:

... var1="1" var2="*" array=(one two three for five)  for elem in ${array[$var1]} do   echo $elem done 

When I use var1 to index in ${array[$var1]} it works correctly, but if I use var2 doesn't work correctly, I get this error:

./ed.sh line XXX *: syntax error: operand expected (error token is "*") 

I'm pretty sure that the error is related with the * wildcard expansion, but I didn't find an answer that help me to solve this problem. So, how can I do it?

</div
        
     
     

回答リスト

5
 
vote
vote
ベストアンサー
 

<コード> link_to9 および<コード> edit0 は、配列内の正規要素とは見なされません。繰り返しキーを繰り返すときにはリストされておらず、インデックス変数を介して間接的に拡張されている場合は考慮されません。

bash ソースコード <コード> edit3 998877623 が使用されているかどうかを確認する関数 edit1 があり、それが文字通りではなく拡張を通して行われていることを確認できます。 :

<事前> <コード> edit4

本当にこれをしたい場合は、変数間の間接が行くことができます:

<事前> <コード> edit5

これらの特別なアレイアクセスモードを配列要素として扱うことを試みていないのが難しいかもしれません。

 

* and @ are not considered regular elements in the array. They are not listed when iterating keys, and are not considered when expanding indirectly through index variables.

The bash source code has a function chk_atstar that checks whether [@] or [*] is being used, and you can see that it's done literally and not through any expansion:

else if (valid_array_reference (name, 0))   {     temp1 = mbschr (name, '[');     if (temp1 && temp1[1] == '@' && temp1[2] == ']')       { 

If you really want to do this, you can go through variable indirection:

arr=(one two three) index='*' var="arr[$index]" echo "${!var}" 

though you may be better off not trying to treat these special array access modes as array elements.

</div
 
 
1
 
vote

これをお勧めしませんが、完全な場合 eval

を使用して拡張注文で不正行為をすることでこれを機能させることができます。 <事前> <コード> eval items=${array[$var2]} for elem in $items do echo $elem done

これに問題があります。 <コード> eval は一般に、変数からコードを実行するのにセキュリティに影響する可能性があるため、一般的に「悪」は発音されます。 eval を使用するよりも、通常、ジョブを実行するためのより良い方法があります。この場合、あなたはデザインにいくつかの考えを与えるべきです。

要素に埋め込み空白が含まれている場合も問題があります。追加:

<事前> <コード> array+=('at the end')

アレイ宣言の後、私が意味するものを見ます。

編集:いくつかの審議の後、 eval なしでを実行する方法は埋め込みスペースまたはタブをサポートしています(まだ埋め込まれていません)。かわいいものではありません:

<事前> <コード> display_it() { if [[ $1 = '*' ]]; then oldIFS="$IFS" IFS=$' ' echo "${array[*]}" IFS="$oldIFS" else echo "${array[$1]}" fi } var1="1" var2="*" array=(one two three for five) array+=('at the end') while read -r elem do echo $elem done < <(display_it "$var2")

表示:

<事前> <コード> one two three for five at the end

ループの最後には、プロセス置換が表示されます。ここで、関数 display_it を呼び出します。読み取られた各項目は改行によって区切られているので、関数内の内部フィールド区切り文字(<コード> IFS )のスワッピング。

 

I don't recommend this, but for completeness you can get this to work by cheating with the expansion order using eval:

eval items=${array[$var2]} for elem in $items do     echo $elem done 

There are issues with this. eval is generally pronounced "evil" because there can be security implications in running code from a variable. There is usually a better way to do the job than using eval. In this case you should give some thought to the design.

There is also an issue if an element contains embedded whitespace. Add:

array+=('at the end') 

After the array declaration and you'll see what I mean.

EDIT: After some deliberation, here is a way to do it without eval, and it supports embedded spaces or tabs (but not embedded newlines). Pretty it is not:

display_it() {     if [[ $1 = '*' ]]; then         oldIFS="$IFS"         IFS=$' '         echo "${array[*]}"         IFS="$oldIFS"     else         echo "${array[$1]}"     fi }  var1="1" var2="*" array=(one two three for five) array+=('at the end')  while read -r elem do   echo $elem done < <(display_it "$var2") 

Displays:

one two three for five at the end 

At the end of the loop you will see process substitution where I call the function display_it. Each item read is separated by a newline, hence the swapping of the Internal Field Separator (IFS) in the function.

</div
 
 
 
 

関連する質問

26  SQL全文索引付けが#を含む単語の結果を返すのはなぜですか?  ( Why doesnt sql full text indexing return results for words containing ) 
例えば、SQL Server 2005を使用して、次のようなマイクエリは次のようなものです。 <事前> <コード> SELECT * FROM Table WHERE FREETEXT(SearchField, 'c#') 使用時に結果を返す列Searc...

66  データベース列を索引付けする方法  ( How do i index a database column ) 
うまくいけば、私はデータベースサーバーごとに回答を受けることができます。 索引付けの仕組みの概要については、データベースの索引付けがどのように機能しますか? ...

2520  データベースのインデックス作成はどのように機能しますか? [閉まっている]  ( How does database indexing work ) 
閉鎖。この質問はもっと焦点を絞ったにする必要があります。現在答えを受け付けていません。 この質問を改善したいですか?このPOST...

0  PHPで大規模なデータを、すべての数値、10億のバイトを検索  ( Searching large data all numeric 1 billion bytes in php ) 
私は、私はすぐにデータの10億バイトまでのデータ列を検索することができるか疑問に思いました。データはすべての数値です。それが何かを見つけるまで現在、我々は、250Kのファイルと、各ファイルにstrpos(最速のビルトイン機能を)使用した検索にデータ分割を持って...

2  MySQLデータベースの吊り下げに関する単純なSELECTステートメント  ( Simple select statement on mysql database hanging ) 
私は非常に大きいテーブルに非常に単純なSQL SELECT文を持っています。 (私のデザインではありません、私は同時に再設計の所有者を納得させようとしている間最適化しようとしています) 基本的には、このステートメントは次のようなものです。 <事前> <コード>...

1  Sphinxが無限の記録を索引付けすることを考える  ( Thinking sphinx indexing non expired records ) 
今日の日付がレコードの「expires_at」フィールド以下であるSphinxのみの索引記録のみを考えるのに最良のアプローチは何でしょうか? 事前にありがとうございました。 ...

4  インデックスとテーブルの統計が古くなっているかどうかを調べる  ( Find out if index and table statistics are out of date ) 
フルスキャン毎週のインデックスを更新します。だから私が走るとき: <事前> <コード> SELECT name AS index_name, STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated FROM sys.in...

12  このクエリにインデックスが使用されないのはなぜですか?  ( Why isnt index used for this query ) 
私はそれがあることがあると思ったときにインデックスが使用されなかったクエリを持っていたので、私は好奇心からそれを再現しました: test_table を1.000.000行で作成します(<コード> col の10個の異なる値、<コード> COUNT2 )。...

22  合計列をインデックス  ( Index a sum column ) 
合計されている列のインデックスを作成しているのは、インデックスがないより速いですか? ...

11  ID!= IDの予期せぬテーブルスキャン  ( Unexpected table scan for id id ) 
1つのアプリケーションにより、SQL Server 2005データベースに大きな負荷がかかります。 このクエリを実行するアプリケーションを制御しません。 <事前> <コード> select id,col1,col2,col3 from table where...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有