awkはあるテキストを一行づつ読み込んで、それを加工してテキストを出力する処理に適している。ここでは以下のようなファイル”01.txt”を考える。
1 2 3 4 5 6 7 8 9 10 11 |
00:01 00:05 I'm going to talk today about energy and climate. 00:05 00:07 And that might seem a bit surprising because 00:07 00:12 my full-time work at the foundation is mostly about vaccines and seeds, 00:12 00:15 about the things that we need to invent and deliver 00:15 00:20 to help the poorest two billion live better lives. 00:20 00:25 But energy and climate are extremely important to these people, |
このファイルを以下のようにしたい。
1 2 3 4 5 6 7 |
00:00:01.000,00:00:05.000 I'm going to talk today about energy and climate. 00:00:05.000,00:00:07.000 And that might seem a bit surprising because .... |
まず01.txtには空行が含まれるのでこれを削除したい。しかし実際には空行ではなくてスペースが一個含まれているのでその行を削除したい。
その前に基本の整理。以下のようにawkを実行すると、元のファイルがそのまま表示される。
1 |
$ awk '{print}' 01.txt |
このコマンドの意味は、01.txtから一行ずつ読み込んで、それをprintで表示するという意味になる。これは以下のように書いても同じ。
1 |
$ awk '{print $0}' 01.txt |
$1とか$2にすると、その行がコマンドライン引数で渡られているかのように、$1,$2に入っていく。
aが含まれる行を表示するには以下のようにする。
1 |
$ awk '/a/{print}' 01.txt |
こうすると、printが実行されるのはaが含まれる行だけになる。aが含まれない行を表示するには以下のようにする。
1 |
$ awk '!/a/{print}' 01.txt |
なので、スペースだけが含まれる行でない行だけ表示するには以下のようになる。
1 |
$ awk '!/^ $/{print}' 01.txt |
^は行の最初をあらわし、$は行の最後をあらわすのでその間にスペース一個入れておけば、スペースだけ含んだ行になる。
これを実行して02.txtにする。
1 |
$ awk '!/^ $/{print}' 01.txt > 02.txt |
本当の空行も削除して、03.txtにする。
1 |
$ awk '!/^$/{print}' 02.txt > 03.txt |
ここからは本格的にやらないといけないので、コマンドラインではなく、ファイルにプログラムを書いて実行する。
その前に基本ちしき。
以下の文
1 |
$ awk '{print}' 03.txt |
これは以下と同じ。
1 |
$ awk -f myawk 03.txt |
myawkはファイルで中身は以下
1 2 3 |
{ print } |
よってmyawkでうまくプログラムを書いて目的を達成したい。
まず、元のファイルは3つの部分、開始時間、終了時間、テキストに分かれるて、これを時刻の行とテキストにする。まずは時刻の行を考えて以下のようにする。
1 2 3 4 5 6 7 |
{ starttime="00:00:" $1 ".00" endtime= "00:00:" $2 ".00" timeline=starttime "," endtime print timeline } |
awkは変数はいきなり使うことができる。文字列の連結は文字列を並べて書くことで行う。+を使うと算数の足し算のように頑張ってしまうので駄目。
次にテキストの行を考えて以下のようにした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{ starttime="00:" $1 ".00" endtime= "00:" $2 ".00" timeline=starttime "," endtime print timeline $1="" $2="" sub(/^ +/, "", $0) print $0 print "" } |
$1と$2に空文字を設定すると、$0からそれらが消える。しかしそれでも先頭にスペースが入ってしまうのでsub組み込み関数でそれらを取り除いて表示する。最後に空行を表示して完成した。
最後に上記のすべてを一行でやると以下のようになる。
1 |
$ awk '!/^ $/ && !/^$/{print "00:" $1 ".000,00:" $2 ".000";$1="";$2="";sub(/^ +/,"",$0);print $0; print ""}' 01.txt |
上記のすべては自分の目的のためだけ+awkの勉強のためなのでここに書いてあることはかなりいいかげんか冗長で汎用性のないものなので注意してください。