はじめに
こちらの記事の続き。
作るもの
今回は指定した列項目のみ抜き出す処理について。
- データベースの作成・更新と全行全項目の出力
- 全感染者の指定項目を取得 (列の抽出,並べ替え) <== 今回はこれ
- 指定項目の条件でフィルタ (行の抽出)
- 指定項目の内訳集計 (出現回数のカウント)
以降では、前回同様作るスクリプト名をcovid
とした前提で説明する。
実行イメージ
以下のように、引数で欲しい列名を欲しい順で指定する。
$ covid date age sex area2 status 確定日,年代,性別,居住地,状態 2020/01/15,30,男性,神奈川県,退院 2020/01/24,40,男性,中華人民共和国,退院または死亡 2020/01/25,30,女性,中華人民共和国,退院または死亡 ... ... 2020/05/13,不明,不明,東京都,
列項目について
前回も載せたけど、指定可能な列項目は以下。
項目 | パラメータ | 備考 | 出力例 |
---|---|---|---|
ID | id | データの通し番号。元データの「通し」 | 1/2/3... |
確定日 | date | PCR検査の陽性確定日 | '2020/05/13'など |
受診都道府県 | area1 | 陽性確定時に感染者が受診していた医療機関がある都道府県。空港名もある... | 東京都/沖縄県/不明など |
居住地 | area2 | 感染者の住居都道府県または居住国 | 東京都/沖縄県/不明など |
居住地(詳細) | area3 | 元データ項目では「キー」。居住都道府県と同じデータも多数 | 東京都/沖縄県那覇市/不明など |
年代 | age | 感染者の年代。元データは100歳以上も90に含むっぽい | 0/10/20/30/40/50/60/70/80/90/100/不明 |
性別 | sex | 感染者の性別 | 男性/女性/不明 |
職業 | job | 感染者の職業。記載がある件数が少なく同職種でも記載に統一感なし... | 会社員/看護師/無職/不明(#1)など |
備考 | note | 詳細地区や年齢やその他補足情報っぽい | 足立区/100歳以上/再陽性 |
状態 | sts | 感染者の状態。元データの「ステータス」と「無症状病原体保有者」の組み合わせ | 死亡/退院/退院または死亡(国内無症状)/空欄 |
年代については元データをスクリプトで以下のように加工して出力する。
元データ | 出力 | 備考 |
---|---|---|
0-10 | 0 | 10歳未満 |
90 | 100 | 備考に「100歳以上」と記載がある場合のみ |
空欄 | 不明 |
コード
列の並び替え関する主要コードは以下。
コード全体はこちらを参照されたし。
引数チェック
列名が不正でないかは以下でチェック。怠いコードですな。
ERR_MSG
が空でなかったらメッセージを出力して実行終了する。
for field in "$@";do case $field in id | date | area1 | area2 | area3 | age | sex | job | note | sts ) ;; * ) ERR_MSG="invalid field-name '$field'" ;; esac done
引数の列名をawkの列位置へ
引数で列項目名を指定した場合、awk
の列位置に置き換える。
OUTPUT_ITEMS='$0' if [ $# -gt 0 ]; then OUTPUT_ITEMS=`echo "$*" | $NAME_TO_POS | sed -e 's/[ ]\{1,\}/,/g'` fi
上記の$NAME_TO_POS
にセットしている関数は以下。
またまた怠いコードですな。
item_name_to_pos(){ sed -e 's/id/$1/g' \ -e 's/date/$2/g' \ -e 's/area1/$3/g' \ -e 's/area2/$4/g' \ -e 's/area3/$5/g' \ -e 's/age/$6/g' \ -e 's/sex/$7/g' \ -e 's/job/$8/g' \ -e 's/note/$9/g' \ -e 's/sts/$10/g' }
列位置は、このスクリプト用に作っているDBファイル($ITEM_DB_FILE)の列位置。
元データのCSVの列位置じゃない点に注意。
指定列項目を出力
出力するのは前回と同じ以下のコード。
先程のコードで$OUTPUT_ITEMS
にはawk
で使える列位置が入っているので、
これだけで好きな列を自由に指定できちゃう。
else # output pickup recodes cat "$DB_FILE" \ | awk -F"," ' BEGIN{ OFS="," } '"$PICKUP_COND"'{ print '"${OUTPUT_ITEMS}"' }' fi
$PICKUP_COND
につてはまた次回。
さいごに
今回はここまで。
基本的にUnixコマンドは行指向で列の処理が苦手な印象だけど、awk
は強い。
指定列だけ抜き出したり入れ替えたりする処理はよくありそうなので、
汎用的な列の抽出入れ替えコマンドを作っておくのもいいかもかも。
そんなawk
は次回も大活躍。好ご期待。
確認環境
PC | Thinkpad X1 Carbon 2nd Gen |
OS | FreeBSD 12.1-RELEASE-p4 |