awkを使ったデータ加工


普段Salesforceに取り込むデータを加工するためにLinux上のシェルを活用しています。シェルで起動できればawkやsed、phpなどを駆使して加工しています。

# 今回は以下のような不完全なデータを整形します。

```
01 1111 A担当 14032 市役所 2207 235 45 2206 73 25 2205 373 142 2204 120 29 2203 _ _ 2202 220 83 2201 _ _ 2112 212 77 2111 256 97 2110 118 41 2109 212 82 2108 4 1 2107 177 58 2106 195 61 2105 19 4 2104 73 26 2103 215 85 2102 316 91 2101 32 22 2012 73 27 2011 299 93 2010 8 2 2009 362 123 2008 219 81
01 1111 A担当 15855 〇×商事㈱ 2207 99 21 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
```

フォーマットは以下のとおりです。
```
#01.営業所c    02.担当者c    03.担当者     04.得意先c    05.得意先名
#06.1ヶ月前    07.1ヶ月前売  08.1ヶ月前粗  09.2ヶ月前    10.2ヶ月前売
#11.2ヶ月前粗  12.3ヶ月前    13.3ヶ月前売  14.3ヶ月前粗  15.4ヶ月前
#16.4ヶ月前売  17.4ヶ月前粗  18.5ヶ月前    19.5ヶ月前売  20.5ヶ月前粗
#21.6ヶ月前    22.6ヶ月前売  23.6ヶ月前粗  24.7ヶ月前    25.7ヶ月前売
#26.7ヶ月前粗  27.8ヶ月前    28.8ヶ月前売  29.8ヶ月前粗  30.9ヶ月前
#31.9ヶ月前売  32.9ヶ月前粗  33.10ヶ月前   34.10ヶ月前売 35.10ヶ月前粗
#36.11ヶ月前   37.11ヶ月前売 38.11ヶ月前粗 39.12ヶ月前   40.12ヶ月前売
#41.12ヶ月前粗 42.13ヶ月前   43.13ヶ月前売 44.13ヶ月前粗 45.14ヶ月前
#46.14ヶ月前売 47.14ヶ月前粗 48.15ヶ月前   49.15ヶ月前売 50.15ヶ月前粗
#51.16ヶ月前   52.16ヶ月前売 53.16ヶ月前粗 54.17ヶ月前   55.17ヶ月前売
#56.17ヶ月前粗 57.18ヶ月前   58.18ヶ月前売 59.18ヶ月前粗 60.19ヶ月前
#61.19ヶ月前売 62.19ヶ月前粗 63.20ヶ月前   64.20ヶ月前売 65.20ヶ月前粗
#66.21ヶ月前   67.21ヶ月前売 68.21ヶ月前粗 69.22ヶ月前   70.22ヶ月前売
#71.22ヶ月前粗 72.23ヶ月前   73.23ヶ月前売 74.23ヶ月前粗 75.24ヶ月前
#76.24ヶ月前売 77.24ヶ月前粗
```

本来なら年月のカラムである6カラム目に2207、9カラムに2207、12カラムに2205 ... と入って欲しかったのですがありません。
また全部なかったらまだ簡単でしたが、何故か１つのカラムだけ値が入ってないようなこともありそうです。

そのため、年月のカラムがブランクの場合に正しい年月を挿入するようなプログラムを作りたいと思います。

# データ加工の考え方

以下のような流れでできると思います。

1. まずはすべての年度フィールドにただしく値が入っているであろうレコードを探します。
2. 上記レコードをマスターとして各年度フィールドの値を変数として作成します。
3. 全てのレコードに対してもし年度フィールドがブランクの場合は該当する年度変数より正しい値をセットします。

# 実際のコード

```
# 年月を抜く
cat $lv3d/SalesResults  |
awk 'NR >1{print $0}' | ##先頭行を抜く
awk '$6 !="_"{print $0}'|
awk '$9 !="_"{print $0}'|
awk '$12 !="_"{print $0}'|
awk '$15 !="_"{print $0}'|
awk '$18 !="_"{print $0}'|
awk '$21 !="_"{print $0}'|
awk '$24 !="_"{print $0}'|
awk '$27 !="_"{print $0}'|
awk '$30 !="_"{print $0}'|
awk '$33 !="_"{print $0}'|
awk '$36 !="_"{print $0}'|
awk '$39 !="_"{print $0}'|
awk '$42 !="_"{print $0}'|
awk '$45 !="_"{print $0}'|
awk '$48 !="_"{print $0}'|
awk '$51 !="_"{print $0}'|
awk '$54 !="_"{print $0}'|
awk '$57 !="_"{print $0}'|
awk '$60 !="_"{print $0}'|
awk '$63 !="_"{print $0}'|
awk '$66 !="_"{print $0}'|
awk '$69 !="_"{print $0}'|
awk '$72 !="_"{print $0}'|
awk '$75 !="_"{print $0}'|
awk 'NR ==1{print $0}' | ##先頭行
cat > $tmp-mas

mas6=`cat $tmp-mas | self 6`
mas9=`cat $tmp-mas | self 9`
mas12=`cat $tmp-mas | self 12`
mas15=`cat $tmp-mas | self 15`
mas18=`cat $tmp-mas | self 18`
mas21=`cat $tmp-mas | self 21`
mas24=`cat $tmp-mas | self 24`
mas27=`cat $tmp-mas | self 27`
mas30=`cat $tmp-mas | self 30`
mas33=`cat $tmp-mas | self 33`
mas36=`cat $tmp-mas | self 36`
mas39=`cat $tmp-mas | self 39`
mas42=`cat $tmp-mas | self 42`
mas45=`cat $tmp-mas | self 45`
mas48=`cat $tmp-mas | self 48`
mas51=`cat $tmp-mas | self 51`
mas54=`cat $tmp-mas | self 54`
mas57=`cat $tmp-mas | self 57`
mas60=`cat $tmp-mas | self 60`
mas63=`cat $tmp-mas | self 63`
mas66=`cat $tmp-mas | self 66`
mas69=`cat $tmp-mas | self 69`
mas72=`cat $tmp-mas | self 72`
mas75=`cat $tmp-mas | self 75`

cat $lv3d/SalesResults  |
awk 'NR >1{print $0}' | ##先頭行を抜く
sort -k 1,5 -t " "  |
awk '$4=="15815"{print $0}' |
awk '$6 =="_"{$6='$mas6'}
     $9 =="_"{$9='$mas9'}
     $12 =="_"{$12='$mas12'}
     $15 =="_"{$15='$mas15'}
     $18 =="_"{$18='$mas18'}
     $21 =="_"{$21='$mas21'}
     $24 =="_"{$24='$mas24'}
     $27 =="_"{$27='$mas27'}
     $30 =="_"{$30='$mas30'}
     $33 =="_"{$33='$mas33'}
     $36 =="_"{$36='$mas36'}
     $39 =="_"{$39='$mas39'}
     $42 =="_"{$42='$mas42'}
     $45 =="_"{$45='$mas45'}
     $48 =="_"{$48='$mas48'}
     $51 =="_"{$51='$mas51'}
     $54 =="_"{$54='$mas54'}
     $57 =="_"{$57='$mas57'}
     $60 =="_"{$60='$mas60'}
     $63 =="_"{$63='$mas63'}
     $66 =="_"{$66='$mas66'}
     $69 =="_"{$69='$mas69'}
     $72 =="_"{$72='$mas72'}
     $75 =="_"{$75='$mas75'}
              {print $0} ' |
cat
```

思ったより簡単にできました。

プログラムは一切作成せずに、既存のコマンドとawkだけでできた。これってローコード開発じゃないの？
考えたら昔からやってるよ。Unixの世界では当たり前のことだけど。