4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

LINUX x AWK: AWKってなんじゃらほい。

Last updated at Posted at 2016-12-02

シェル芸について調べてた時にAWK使えたほうがいいよAWK!
ってな情報に出会ったんだけどAWKってなに?おーく?豚なの?

みたいなレベルからとりあえずどんなものか触ってみようと思ってまとめてみました。


AWKってなんやねん? in wikipedia

(1)名前の由来は開発者の名前から。

アルフレッド・エイホ、ピーター・ワインバーガー、ブライアン・カーニハンの三人のLastName取ってAWK。
モンスターとか樫の木じゃないのね。

(2)UNIX上で開発されたプログラミング言語

ぷ、プログラミング言語なの?ツールじゃないのか。

(3)改行でレコードが区切られ、各レコードのフィールドは空白類で区切られているようなテキストファイルを扱えるがカスタマイズも可能。

なるほど、文字列操作のための言語なのね。デフォでCSVファイルとかを操作したい時に使うと。

(4)文字列と数値を扱うプログラミングも可能である。

CUIでEXCEL関数とか使うイメージだろーか?
なんとなくわかった気分になったので一旦座学はおいといて手を動かすことにする。


まずは慣れるためにAWKプログラミングのさわりをいくつか。

こちらを参考にさせていただきました。
https://hydrocul.github.io/wiki/commands/awk.html

(1)とりあえずハローワールド。


awk 'BEGIN { print "Hello, AWK world!" }'

ほむほむ、ワンライナーで書く場合もBEGIN句で開始して中身を記述すると。
ちなみにBEGIN指定しないで以下のように記述すると、なんか延々ハローワールドが表示された。
どんな仕様だ?


awk '{ print "Hello, AWK world!" }'

(2)CSVファイルの中身を単純にプリントしてみる。

サンプルcsv

# awk.txt
1 2 3 4 5
a b c d e
P P A P
awk '{print $1 $2 $3 $4 $5}' awk.txt

>12345
>abcde
>PPAP

ちなみに変数?間の空白は詰めても問題なかった。

(3)四則演算してみる。

# 加算:
awk '{print $1 + $2}' awk.txt

>3
>0
>0

# 減算:
awk '{print $4 - $1}' awk.txt

>-1
>0
>0

# 乗算:
awk '{print $5 * $3}' awk.txt

>15
>0
>0

# 除算
awk '{print $4 / $2}' awk.txt

>2
awk: division by zero
 input record number 2, file awk.txt
 source line number 1

まずわかったのは文字列はゼロとして扱われること。
加減乗まではゼロが計算式に入ってもゼロが吐かれるだけで問題ないけど、
除算の場合ゼロディバイドになってエラーが出る。

(4)区切り文字へんこう。

サンプルCSV

# awkd.txt
1,2,3,4,5
a,b,c,d,e
P,P,A,P

awk -F, '{print $1 $2 $5 $1*$3}' awkd.txt

>1253
>abe0
>PP0

区切り文字はカンマでもパイプでもいけるっぽい。
ちなみにパイプの場合はエスケープがいるようだった。

awk -F\| '{print $1 $2 $5 $1*$3}' awkd.txt

(5)行番号を出力


awk '{print NR $1 $2 }' awk.txt

>112
>2ab
>3PP

# ゼロから始める
awk '{print NR-1 $1 $2 }' awk.txt 

>012
>1ab
>2PP

美しくないけどとりあえず。

(6)検索

awk '/1/' awk.txt

# grepのこれと同じ。

grep 1 awk.txt


オフィシャルから使いそうなコマンドを拾ってくるテスト。

Linuxコマンドと合わせてワンライナーコマンド

(1)対象ファイルの各行のレコード長を表示

## こんなかんじのねろねろなサンプルテキストファイルを用意

aasdasffsanlfkas

asdlasfasdas
sadasdm
fas
sdlkvsfa
12321312rsdvmlsk
23dslks

# コマンド

awk '{print NR":"length($0)}' awk.txt

1:16
2:0
3:12
4:7
5:3
6:8
7:16
8:7

列番号が美しくなかったので : を挟んで見る。

(2)for loop

まずはぐるぐる。


cat awk.txt | 
wc -l | 
xargs -Iline awk '
  {
  for (i=1; i<line ; i++)
    print $i
  }
' awk.txt

手順的には、
(1)awk.txtの中身をcatで展開
(2)wcで行数を取得(直接ファイルから取得するとファイル名が含まれてしまうためパイプ渡し)
(3)変数lineに行数を引数として渡す。
(4)forloopで行数分のレコードをprintする。

(3)FizzBuzz

せっかくなのでFizzBuzzも書いてみる。


awk  '
  BEGIN {
  for (i=1; i<100; i++)
    if (i%3==0 && i%5==0)
      print "FizzBuzz!"
    else if (i%3==0)
      print "Fizz!"
    else if (i%5==0)
      print "Buzz!"
    else
      print i
  }

' 

こうしてみると普通のプログラミング言語なんですねぇ。
ってことでまた何かあれば書きます。

4
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?