1. ホーム
  2. スクリプト・コラム
  3. リナックスシェル

シェルにおける配列とその関連操作の詳細例

2022-01-05 11:29:02

シェルには、文字列、数値型、配列など、いくつかのデータ型があります。配列はその中でも重要なもので、配列の長さを求める、要素の長さを求める、要素を反復する、要素をスライスする、置換する、削除する、などの操作が重要な応用シーンとなり、非常に便利に使うことができるのです。

Shellの配列はJAVA/Cと異なり、2次元配列ではなく1次元配列にしかできないこと、配列要素の大きさに制約がなく、配列の要素数を最初に定義する必要がないこと、しかしそのインデックスがJAVA/C/Pythonと同様に0から始まること、そのよくある方法を以下にまとめます。

[配列の宣言]。

注意事項

1) JAVA/Cのように代入前に宣言しなければならない強いプログラミング言語と異なり、SHELLは事前に宣言してもしなくてもよい弱いプログラミング言語です。

2) 配列を元に戻すにはunsetを使用し、中の要素を削除するにはunset array_name[i]を使用します。

[配列の定義].

注意事項

1) 配列の要素は "空白 "で区切ることが基本です。

2) 配列のインデックスを順番通りに定義する。例えば、names=([0]=Jerry [1]=Alice [2]=David [8]=Wendy) のように定義する。

3) 文字列はSHELLで最も重要なデータ型であり、($str)で配列に変換することもでき、非常に操作しやすくなっています。

[配列の長さ]。

注意事項

1) ${array_name[@]}または${array_name[*]}で、配列の全要素を表示する

2) 同様に ${#array_name[@]} または ${#array_name[*]} を使って、配列の長さを求めることができます。

3) 配列の要素の長さを求める方法はたくさんあり、文字列の長さを求めるのと同等である

[配列インデックス]。

[root@locathost ~]# s="A,B,C,D"
[root@locathost ~]# a=(`echo $s | tr ',' ''`) # turn string into array
[root@locathost ~]# echo ${!a[@]} # Find the index in the array 
0 1 2 3

要素削除

[root@localhost ~]# a=(A B C D)
[root@localhost ~]# unset a[2] # remove the element with index 2
[root@localhost ~]# echo ${a[@]} # Show the deleted elements
A B D

[配列のトラバーサル

スクリプトを出力します。

注意事項

1) 標準的なforループを使用することができます。これは、配列の要素を繰り返し処理するC言語の方法です。

2) for element in element set (array) これはPythonで配列を走査する方法です。

3) コードの可読性と実行速度の点から、2番目の方法を推奨します。

[配列の割り当て]。

注意事項

1) 1つ目は、既存の要素項目を再割り当てすることです

2) もちろん、以下の例のように、存在しないインデックスに値を追加することも可能です。

[配列に追加

画像

[アレイスライス

アレイスライス

画像

要素スライス

注意事項

1) 汎用フォーマット ${array[@]:start position:length} を ":" で区切り、2番目の項目を省略した場合、それ以降の項目は全て採用される

2) スライス後の文字列は,新しい配列 = (${old array[@]:index:length}) のインデックスを持つことができます.

3) Pythonとの違いの1つ、開始位置は負でもよいが、()内に入れる必要があり、長さは負にできないこと

4) Pythonとの違いの2つ目:Pythonの2番目の項目は終了インデックスで、Shellでは取り出した要素の長さを表す

5) Pythonとの違いの3つ目。Pythonはlist[-1:-4:-2]で数値の逆引きが可能ですが、Shellでは不可能です。

[配列置換

${array[@]/x/y}となります。      最小限のマッチング置換、各要素につき1回のみ

配列[@]//x/y}となります。     最大一致置換、要素ごとに複数置換

${array[@]/x/}となります。       最小一致削除、一致する要素を1つだけ削除します。

配列[@]//x/}を指定します。      複数の一致する要素を削除する最大一致削除

${array[@]/#x/y}となります。      左から右へのマッチング置換で、各要素の左端の文字だけを置き換えます。

${array[@]/%x/y}のようになります。      右から左へのマッチ置換で、各要素の右端の文字だけを置換します。

画像

[配列削除

#   各要素、左から右への最短マッチ

## 各要素について、左から右の順に最長一致となります。

%   各要素について、右から左への最短マッチ

%% 各要素について、最長一致は右から左へ

[配列アプリケーション

例1 : ifconfig コマンドで取得したローカル IP: 127.0.0.1 を一行ずつ表示します。

スクリプトを出力します。

画像

例2 スタックのプッシュ、ポップ、シフト、アンシフト操作をシミュレートする。

画像

スクリプトを出力します。

画像

例3 : 1から10までの非繰り返し数字をランダムに10個生成し、配列に配置します。

スクリプトを出力します。

画像

注意事項

1) 範囲 [1,10] で繰り返しのない乱数整数を生成し、配列array に保存する。

2) seq 1 10 1から10までの整数の並びを生成する(境界値は1と10)。

3) rand() 関数の awk で、0 から 1 の間のランダムな小数値を生成 (小数点以下 6 桁を保持)。

(4)一度だけ乱数を生成するためにrand()、転がり生成の乱数を作るためにsrand()関数を使用するために

5)ランダムカウンタのシードとして、現在の時間のデフォルトの使用は、秒の間隔は、乱数がランダムにローリング生成することができるように、括弧を空のままにします。

6) 間隔は秒単位なので、スクリプトを2回連続で実行しても(1秒以内)、生成される乱数は同じであることがわかります。

例4 : 文字列を配列に変換して出力する

スクリプトを出力します。

画像

例5 : 標準入力からread -a引数で配列を読み込んで、次の操作を行う。

スクリプトを出力します。

画像

例6 : ある変数が配列に含まれるかどうかを判定し、含まれる場合はYESを、含まれない場合はNOを出力する

スクリプトを出力します。

画像

例7 : 配列の要素の並べ替え

例8 : etc/passwd ファイルの最初の : 区切られたカラム,すなわちユーザー名を配列に配置します.

例9 : 1から8までの各数値を掛け合わせ、出力する。

スクリプトを出力します。

画像

例 10 : 配列の助けを借りてSHELLS環境変数を設定する

例 10 I:ファイルの中身を読み込むためのIFSの設定例

例 10 II:evalを使って、配列の実装をシミュレーションする

スクリプトを出力します。

画像

例 10 III: 配列を使ったバブルソートの実装

アイデア ソートされる配列に繰り返しアクセスし、一度に2つの要素を比較し、順序が正しくない場合は入れ替えを行う。入れ替えが不要になるまで配列の走査が繰り返され、配列はソートされます。大きな要素は、スワップすることでゆっくりと配列の先頭に「浮いて」いきます。

スクリプトを出力します。

画像

例 14 : 配列を使って最大値を求める

スクリプト出力

画像

概要

シェルにおける配列とその関連操作についての記事は以上です。シェルにおける配列操作の詳細については、BinaryDevelopの過去の記事を検索するか、以下の関連記事を引き続き参照してください。