カテゴリー
Linux

【シェルスクリプト】CSV ファイルの任意のカラムの値がリストにある値と一致したらその行を除きたい。

やりたいことと対象のファイル

  • シェルスクリプトを使いたい。ファイルは exclude_list.sh
  • CSV ファイル (target.csv) の 2 列目の値が除外リストにある値と一致したらその行を除きたい。そして resutl.csv として出力したい。
  • 除外リスト (list.txt) は改行区切りのテキストファイル
  • 登場したファイルはすべて同じディレクトリに置く。

次の CSV ファイルを 1 行ずつ取り出して、2 列目が除外リストにあればその行を取り除きたいのです。

id,value,option
1,北海道,最北
2,東京都,首都
3,愛知県,名古屋
4,奈良県,鹿
5,広島県,原爆
6,沖縄県,最南端

除外リストのテキストファイルは次です。

愛知県
広島県

学んだこと

カンマ区切りのフィールドを指定して切出し

line="1,北海道,最北"
# カンマ区切りの 2 フィールド目を切出し
# -d: 区切り文字
# -f: 切出し対象フィールド
target_column=`echo $line | cut -d',' -f2`
echo "$target_column"

パターンがテキストファイルの行全体とぴったりマッチした行数を取得

“北海道” と “愛知県” のコメント化を切り替えることでマッチしたときとそうでない時の比較が可能です。

target_column="北海道"
#target_column="愛知県"
# パターンがテキストファイルの行全体とぴったりマッチした行数を取得
matched_line_count=`grep -cx $target_column list.txt`
echo "$matched_line_count"
  • Man page of GREP
    • -x, –line-regexp オプション
    • -c, –count オプション

if の判定

1 行目の数字を 0 か 1 以上にすることで判定の切り替わりを確認できます。

matched_line_count=1
# test コマンドを使用して if 判定
# 
if test $matched_line_count -ge 1 ; then
  echo "true"
fi

完成したシェルスクリプト

#!/bin/bash
#
# @(#) exclude_list.sh ver.1.0.0 2017.010.19
#
# Usage:
#   exclude_list.sh
#
# Description:
#   target.csv を読込み、
#   2 カラム目の値が list.txt にある行を除外して
#   result.csv に出力します。
#
###########################################################################

while read line
do
  # カンマ区切りの 2 フィールド目を切出し
  target_column=`echo $line | cut -d',' -f2`

  # 除外リストに存在する場合はスキップ
  matched_line_count=`grep -cx $target_column list.txt`
  if test $matched_line_count -ge 1 ; then
    continue
  fi

  # ファイルへ書き込み
  echo $line >>result.csv
done <target.csv

おわりに

awk コマンドを使えば、もっと短く書けそうに思います。まずは愚直に処理してみました。

以上です。

コメントを残す