2011年6月30日木曜日

sedコマンドを使う

シェルを使って、sqlファイルのある行を削除することをしました。

具体的に何がしたかったのか、というと
$ cat hogehoge.sql

@@atypes_2.1.0-2.2.0.sql                      
@@atypes_2.2.0-2.3.0.sql
@@atypes_2.3.0-2.4.0.sql
@@atypes_2.4.0-2.5.0.sql
@@atypes_2.5.0-2.6.0.sql
@@atypes_2.6.0-3.0.0.sql
@@atypes_3.0.0-3.0.1.sql
EXIT


上のデータを持つhogehoge.sqlに、2.4.5の引数を与えると、繰り下げをした値より小さい値(ex. 2.3.8)が含まれているデータの行を削除して、下記の出力をするシェルを書く必要がありました。

$ cat hogehoge.sql

@@atypes_2.4.0-2.5.0.sql                    
@@atypes_2.5.0-2.6.0.sql
@@atypes_2.6.0-3.0.0.sql
@@atypes_3.0.0-3.0.1.sql
EXIT

これは、awkとsedを使って実現することができます。
そのときのコードです。( \ はエスケープを表しています。Windows系だと、¥に相当することに注意しください)



sql_edit.sh
P_VER=$1

P_NUM=`echo ${P_VER} | sed -e 's/\(.\)\.\(.\)\.\(.\)/\1\2\3/'`

while :
do
ATYPES=`awk 'NR==1' /Users/Taichi/perl_data/sh_sample/hogehoge.sql`                  
ATYPES_NUM=`echo ${ATYPES} | sed -e 's/@@atypes_.\..\..-\(.\).\(.\)\.\(.\)\.sql/\1\2\3/' `                          
if [ ${P_NUM} -lt ${ATYPES_NUM} ];then
        break
fi
sed -i -e '1d' /Users/Taichi/perl_data/sh_sample/hogehoge.sql
done


実行してみます。
$ ./sql_edit.sh 2.5.1
$ cat hogehoge.sql

@@atypes_2.5.0-2.6.0.sql                          
@@atypes_2.6.0-3.0.0.sql
@@atypes_3.0.0-3.0.1.sql
EXIT


■解説
1.
P_NUM=`echo ${P_VER} | sed -e 's/\(.\)\.\(.\)\.\(.\)/\1\2\3/'`
引数として与えた "2.5.1" からコロンを抜いて "251" を P_NUMに与えています。

sedで、特定の文字列を抜き出すことができます。
echo '置換したい文字' | 'sed -e 's/置換条件/置換文字/'
置換条件で、"\(" と "\)" でくくられた文字列が置き換え文字として、順番に \1, \2, ... に代入されます

参考)http://itpro.nikkeibp.co.jp/article/COLUMN/20060228/231161/


2. while の中で if条件を使う
while [ 条件 ]
do
if [ 条件 ];then
        break
fi
done

上記のように、指定します。
実際のコードでwhileの隣にある “:” は常に真になるため、breakを指定しなければ無限ループするので気をつけましょう。

参考)http://shellscript.sunone.me/while.html


3. ATYPES=`awk 'NR==1' /Users/Taichi/perl_data/sh_sample/hogehoge.sql`
hogehoge.sqlの1行目のデータを抽出して、ATYPESに渡しています。

# ファイルのある行のデータを抜き取る
awk ‘NR== (行目) ’ ファイル名

参考)http://uguisu.skr.jp/Windows/awk.html


4. 条件分岐
if [ ${P_NUM} -lt ${ATYPES_NUM} ];then
        break
fi

比較の演算子がなかなか覚えられない・・・
-lt (より小さい)
-le (以下)
-eq (等しい)
-gt (より大きい)
-ge (以上)
-ne (等しくない)

参考)http://akitosblog.seesaa.net/article/186865411.html


5. sed -i -e '1d' /Users/Taichi/perl_data/sh_sample/hogehoge.sql
hogehoge.sqlの1行目を削除して、上書きしています。

# 単一行の削除
sed -i -e '行番号d' ファイル名

参考)http://shellscript.sunone.me/filter_sed.html

0 件のコメント:

コメントを投稿