以下のようなファイルがあるとする。
$ cat t1.txt
ag,a1
bg,b1
cg,c1
dg,d1
eg,e1
ag,a1
ag,a2
ag,a2
ag,a3
ag,a1
ag,a2
ag,a1
ag,a4
ag,a3
bg,b1
bg,b4
bg,b3
bg,b6
bg,b3
cg,c1
cg,c3
cg,c4
dg,d2
dg,d3
dg,d2
dg,d6
eg,e2
CSVファイルですね。
1カラム目をグループID
2カラム目をメンバーID
とした時、グループIDとメンバーIDの重複をとりグループIDを配列変数としその変数に属するメンバーを代入(初期化)してみよう。
というシェルを考えて作成してみよう。
とこんな感じ
$ cat t1.sh
#!/bin/sh
IN_FILE=t1.txt
GID_LIST=" "
for f in `cat ${IN_FILE}|awk -F, '{print $1}' | sort | uniq `
do
PID=`echo -n |grep $f $IN_FILE | awk -F, '{print $2}' | sort | uniq`
eval $f="( $PID )"
GID_LIST="${GID_LIST} $f"
done
for f in ${GID_LIST}
do
eval echo ${f} \$\{\#${f}\[\@\]\} \$\{${f}\[\@\]}
done
こんな感じ!!
それじゃ実行してみよう!!
$sh t1.sh
ag 4 a1 a2 a3 a4
bg 4 b1 b3 b4 b6
cg 3 c1 c3 c4
dg 4 d1 d2 d3 d6
eg 2 e1 e2
$
結果の説明
スペース区切りのCSVファイル
1カラム目はグループID
2カラム目はメンバーの数
3カラム目以降は1カラム目のグループIDに属するメンバーIDのリスト
簡単な説明
配列変数のメンバー数を取り出すところ
${#ARRAY[@]}
ARRAYが変数fになっているので ${f} なるね!!
これをメンバー数#を指定
¥#${f}
配列全体を意味する [@] をくっつける。
¥#${f}¥[¥@¥]
順序よく説明するからエスケープさせるための ¥ がなぜそこに必要かわかってもらえると思います。
さ、次に全体を一つの変数として意味づけるための ${} で囲えるようにしよう。
\$\{\#${f}\[\@\]\}
このままだとどうなるのか?
$ f=ag
$ ag=(a1 a2 a3 a4)
$ echo ${f}
ag
$ echo \$\{\#${f}\[\@\]\}
${#ag[@]}
さ、一瞬間抜けなechoが出ましたか?!
でも大丈夫、${#ag[@]} が出せるということは eval を使えばいい
$ eval echo \$\{\#${f}\[\@\]\}
4
さ、おじさんの解説は終わり。
またね!!
0 件のコメント:
コメントを投稿