配列(応用)
前回の配列と、前々回の変数への代入を使って、簡単なスクリプトを書いてみましょう。
判っている方からしてみると、面倒な事をやってるなー、なんて思うかもしれませんが、今までの部分の復習という意味での使用例みたいなものですから大目にみてやってください。
さて、こんな要件のスクリプトを書いてみます。
・「ls -l」で出力した情報から、「パーミッション」「オーナーグループ」「オーナーユーザ」「ファイルサイズ」「ファイル名」を抜き出す。
・抜き出した情報を、見出しをつけて1行に1項目ずつ出力する。
長ったらしい要件の割には大した事はやってませんが、とりあえず作ってみましょう。
まず、最初に「ls -l」の出力を確認します。
# ls -l 合計 36 -rwxr-xr-x 1 root root 34 3月 16 21:45 helloworld.sh -rwxr-xr-x 1 root root 55 3月 16 21:45 helloworld2.sh -rwxr-xr-x 1 root root 1030 3月 16 21:45 helloworld3.sh -rwxr-xr-x 1 root root 988 3月 16 21:45 helloworld4.sh -rwxr-xr-x 1 root root 242 3月 16 21:45 helloworld5.sh -rwxr-xr-x 1 root root 196 3月 16 21:45 helloworld6.sh -rw-r--r-- 1 root root 193 3月 16 21:45 helloworld7.sh -rwxr-xr-x 1 root root 374 3月 16 22:20 output02.sh drwxr-xr-x 2 root root 4096 3月 16 21:46 test01 #
私の環境だと上記の様に出力されました。
1 2 3 4 5 6 7 8 9 -rwxr-xr-x 1 root root 34 3月 16 21:45 helloworld.sh
これを見ると、「パーミッション」「オーナーグループ」「オーナーユーザ」「ファイルサイズ」「ファイル名」の項目は、
スペース区切りで考えて、それぞれ 1、3、4、5、9の項目だと判ります。
これを踏まえて以下の様なスクリプトを書いてみましょう。
#!/bin/bash
V_LS=`ls -l`
while read LINE
do
A_LSLINE=(${LINE})
echo -n "perm :"
echo "${A_LSLINE[0]}"
echo -n "grp :"
echo "${A_LSLINE[2]}"
echo -n "own :"
echo "${A_LSLINE[3]}"
echo -n "size :"
echo "${A_LSLINE[4]}"
echo -n "filename:"
echo "${A_LSLINE[8]}"
echo ""
done <<< "${V_LS}"
exit 0
まず、3行目で、「ls -l」の出力を、変数「V_LS」に代入します。
V_LS=`ls -l`
5行目から19行目はループ処理です。
while read LINE
do
A_LSLINE=(${LINE})
echo -n "perm :"
echo "${A_LSLINE[0]}"
echo -n "grp :"
echo "${A_LSLINE[2]}"
echo -n "own :"
echo "${A_LSLINE[3]}"
echo -n "size :"
echo "${A_LSLINE[4]}"
echo -n "filename:"
echo "${A_LSLINE[8]}"
echo ""
done <<< "${V_LS}"
変数「V_LS」に格納された「ls -l」の出力を1行ずつ取り出し、変数「LINE」に入力してます。
このループのポイントは、19行目の「<<<」にあります。
これは「ヒアドキュメント」の一種で「ヒアストリング」といいます。変数などに格納されている値を
取り出してループ処理を行う際は、変数内に格納されている文字列を一度展開する必要がありますので、
この「ヒアストリング」を使用します。
そして、7行目でコマンド出力を1行読み込んだ変数「LINE」を展開し、配列「A_LSLINE」に格納します。
変数「LINE」にある、スペース区切りの各項目を配列の要素へ格納しますので、変数を「()」でグルーピング
してやります。
A_LSLINE=(${LINE})
最初に確認したとおり、出力対象の項目が1,3.4.5.9にあります。
配列の最初の要素は0からですので、それぞれ、0,2,3,4,8の要素が該当する事になります。
これを順に出力するのですが、今回は見出しを別に出力してみました。面倒であれば、見出しも含めて
1行で出力して構わないです。
さて、このスクリプトを実行してみます。
# ./output02.sh perm :合計 grp : own : size : filename: perm :-rwxr-xr-x grp :root own :root size :34 filename:helloworld.sh perm :-rwxr-xr-x grp :root own :root size :55 filename:helloworld2.sh perm :-rwxr-xr-x grp :root own :root size :1030 filename:helloworld3.sh perm :-rwxr-xr-x grp :root own :root size :988 filename:helloworld4.sh perm :-rwxr-xr-x grp :root own :root size :242 filename:helloworld5.sh perm :-rwxr-xr-x grp :root own :root size :196 filename:helloworld6.sh perm :-rw-r--r-- grp :root own :root size :193 filename:helloworld7.sh perm :-rwxr-xr-x grp :root own :root size :322 filename:output02.sh perm :drwxr-xr-x grp :root own :root size :4096 filename:test01 #
大体想定通りに出力されました。
ただ、一番上の「合計」部分が見栄え悪いですね。
ここの対策もしてみましょう。
一番最初に「ls -l」の出力を確認した時、一番上の行はこんな風に出力されていました。
1 2 合計 32
この行を配列に格納すると、こんな感じになるはずです。
0 1 合計 32
と言う事は、配列で言う2番目の要素以降は空だと言う事ですね。
これはこの行以外には当てはまりません。
ですので、こんな感じに修正してみました。
#!/bin/bash
V_LS=`ls -l`
while read LINE
do
A_LSLINE=(${LINE})
if [ "${A_LSLINE[8]}" != "" ]
then
echo -n "perm :"
echo "${A_LSLINE[0]}"
echo -n "grp :"
echo "${A_LSLINE[2]}"
echo -n "own :"
echo "${A_LSLINE[3]}"
echo -n "size :"
echo "${A_LSLINE[4]}"
echo -n "filename:"
echo "${A_LSLINE[8]}"
echo ""
fi
done <<< "${V_LS}"
exit 0
8行目のif文で、「8番目の要素(ファイル名)が空文字列以外のもの」という条件をつけました。
これによって、ファイル名の要素が無い場合は出力されません。
1行目にはファイル名の要素はありませんので想定通りです。
さっそく実行してみましょう。
# ./output02.sh perm :-rwxr-xr-x grp :root own :root size :34 filename:helloworld.sh perm :-rwxr-xr-x grp :root own :root size :55 filename:helloworld2.sh perm :-rwxr-xr-x grp :root own :root size :1030 filename:helloworld3.sh perm :-rwxr-xr-x grp :root own :root size :988 filename:helloworld4.sh perm :-rwxr-xr-x grp :root own :root size :242 filename:helloworld5.sh perm :-rwxr-xr-x grp :root own :root size :196 filename:helloworld6.sh perm :-rw-r--r-- grp :root own :root size :193 filename:helloworld7.sh perm :-rwxr-xr-x grp :root own :root size :374 filename:output02.sh perm :drwxr-xr-x grp :root own :root size :4096 filename:test01 #
どうです?
ちゃんと出力されましたでしょうか?
