2009年3月29日日曜日

シェルスクリプトの本

シェルスクリプトに関する書籍は沢山出ています。情報としては当たり前のものから、「オォッ!」と思える Tips も載っていたりします。正直、完璧なリファレンスはないですので、何冊か揃えておくのが無難です。まあ、2冊か 3冊くらいでしょうか。

tr、sed、awk 等の使い方は詳しくは載っていないものが多いです。サンプルスクリプトが掲載されていて、その例通りに使うということが多いです。

それよりも特殊変数の使い方や sh コマンドと . コマンドの違い等、基本的な解説がされているものがいいと思います。

お勧めはこれです。
入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界
入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界

2009年3月28日土曜日

awk No.004(条件指定)

awk の条件指定はいろいろあります。

まず、空行を除く場合は、以下のように NF > 0 を指定します。余計なデータを除いて処理する場合の基本です。ここで使っている NF は読み込んだレコードのフィールド数(データ数)を表わしています。NF が 0 よりも大きい、すなわち 1 個以上の場合は処理をするという指定になります。(空行はデータがないので処理しないということになります。)

awk 'NF > 0 {print $1}' a.dat
空行を除く場合は、以下のようにもできます。どちらかといえばこちらの方が本当の意味で空行を判定しています。^$ は正規表現で先頭と行末で、先頭と行末のみということは空行で、それを ! で否定していますので、空行ではない行という条件になります。データが無いという条件より厳密です。
awk '!/^$/ {print $1}' a.dat
何番目のレコードを処理するというように、レコードの順番を指定して処理する場合は、以下のように NR を使います。例えばデータファイルに行タイトルがある場合は、1行目を読み飛ばす等の処理ができます。
awk 'NR > 1 {print $1}' a.dat
基本的な使い方をもう一つ。読み込んだデータの内容によって処理をするかどうかを判定します。1番目のフィールドのデータが 100 より大きい場合に処理をするといった使い方は以下の通りです。
awk '$1 > 100 {print $1}' a.dat

2009年3月24日火曜日

awk No.003(区切り文字、デリミタ、フィールドセパレータを変更)

awk 標準の入力データのデリミタはスペースです。デリミタを変更したいときは、変数 FS を使います。デリミタと書きましたが、FS という変数からわかるようにフィールドセパレータというのが区切り文字の正式名称(?)のようです。

使い方は以下の通りです。

$ cat a.dat
a:b:c
d:e:f
g:h:i

$ awk -v FS=":" '{print $1}' a.dat
a
d
g

2009年3月18日水曜日

awk No.002(データを積算、演算)

awk の便利なところは値の積算などが手軽にできるところです。例えば、ある列の値を加算して変数に入れたり、複数の列を演算した結果を表示したりできます。

# cat a.txt
a 1 2
b 3 4
c 5 6
d 7 8

# awk '{SUM += $2;print $1,$2,SUM}' a.txt
a 1 1
b 3 4
c 5 9
d 7 16
# awk '{VAR = $2 + $3;print $1,$2,$3,VAR}' a.txt
a 1 2 3
b 3 4 7
c 5 6 11
d 7 8 15

2009年3月15日日曜日

awk No.001(基本的な使い方と変数の使い方)

awk は便利です。今更ですが。

sed をもっと高機能にしたものとも言えますが、実際はデータの置き換えというよりも、データの抽出、整形に特化しているコマンドだと思います。

ファイルを順に読んでいき処理をしてくれるわけですが、基本的な使い方は以下の通り。

awk '条件{処理}' filename
条件には、処理対象とする行の条件を指定します。処理は文字通り、処理です。print $1 等と指定すれば処理対象の1列目のデータを表示します。

スクリプト内で、$1 等を変数として使いたい場合は、以下のようにします。
[OK]
# cat a.txt
abc 0 1 2
def 0 1 2
ghi 0 1 2
jkl 0 1 2

NUM="1"
awk -v NUM=${NUM} '{print $NUM}' a.txt

実行結果
abc
def
ghi
jkl
-v オプションで NUM という awk 内の変数に、シェルスクリプト内の変数を代入して、awk 内の変数 NUM として使います。

以下のような指定では、思った結果は得られません。NUM は"$1"という文字列が代入された awk 内の変数として扱われ、$1 が結果として表示されてしまいます。
[NG]
# cat a.txt
abc 0 1 2
def 0 1 2
ghi 0 1 2
jkl 0 1 2

NUM="$1"
awk -v NUM=${NUM} '{print NUM}' a.txt

実行結果
$1
$1
$1
$1

2009年3月5日木曜日

df で表示させるファイルシステムを限定する

df コマンドでファイルシステム情報を表示すると、NFS 等のネットワークファイルシステムを多くマウントしていたり、ローカルファイルシステムが多くあったりすると、だらだらと表示されて見づらくなってしまいます。

そこで、-x (--exclude=) オプションで、表示させないファイルシステムを指定することができます。また、複数のファイルシステムタイプを指定したい場合は、-x (--exclude=) オプションを複数回指定します。

df -x nfs -x ext2