bashで行列データベースの特定行を読み出し一度に複数の変数を定義する方法


1. 目的

n行m列のテキストデータベースがあったとします。それから指定の行の要素を読み出して、複数の変数に格納します。面倒なので配列は使いたくありません。

2. 環境

  1. CentOS 7.
  2. bash 4.2

3. 考え方

指定行をsedで読み出してそれをread渡して変数に設定する。

4. テスト用のデータベース

  • 第1列は重なりのない1刻みの数字だとします。データの列の並びはNUM MAKER MODEL TYPEとします。例えば、
$ cat data.txt
1 apple iPhone AAA
2 google Android BBB
3 sony Walkman CCC

5. コード

$ cat test.bash
#!/usr/bin/bash 
read NUM MAKER MODEL TYPE <<< $(sed -n "${1}p"  $2)
echo "$MAKER" "$TYPE" "$NUM" "$MODEL"
  • 説明:
    • readは変数を複数設定できます。そのreadに文字列を渡します。
    • 実行したコマンド結果を<<< $()で文字列として取り出します
    • sed-nで非表示にして、数字pで指定行だけ表示します。
    • sedに表示行数とファイルを$1$2で渡します。
    • 最後のechoで変数がグローバル変数であることを確認しています。順番も変えて確かめています。

6.結果

$ ./test.bash 1 data.txt
apple AAA 1 iPhone
$ ./test.bash 2 data.txt
google BBB 2 Android
$ ./test.bash 3 data.txt
sony CCC 3 Walkman
$ 
  • 大丈夫なようです。普通に考えると
    • MAKER=$(awk '$1 == 1{print $2}' data.txt) みたいなコード書きがちですが、変数が多いと長くなりがちです。
  • データベースとして情報を行列にして、レコードをユニークなシリアル数字で管理するという基本形を採用するとbashでもシンプルにコードが書けます。アルゴリズムよりデータ構造が大切ですね。データベースの登録時に重なりがないことのチェックとか、情報の削除はレコードは残しフィールドだけvoidにするとか、それなりに気を使う必要がありますが、読み出すのは楽です。
  • こんな短いコードでデータベースを扱えるのでbash好きです。ちょっとしたアイディアですが、どなたかのお役に立てると嬉しいです。