カテゴリー
【実践!CSVデータ検索スクリプト作成編】CSVデータの複数列から複数条件で検索して行データを表示させるスクリプト
※ 当ページには【広告/PR】を含む場合があります。
2021/04/12
はじめに
スクリプトツールの概要
山田
佐藤
モフ雄
$ ./simple_finder.sh -i search_list.csv employee.csv
山田の項目...
佐藤の項目...
モフ雄の項目...
山田,製造,,
子,,名古屋,
モフ雄,,,16年
川,製造,,14年
ツールスクリプトの修正
#!/bin/bash
usage_exit() {
echo "USAGE: $(basename $0) [-l key_list] [-h help] [input_file]" 1>&2
exit 1
}
noarg_err() {
echo "ERROR: must provide key_list!" 1>&2
exit 1
}
selecteither_err() {
echo "ERROR: should select an option from -l/-i!" 1>&2
exit 1
}
noinputfile_err() {
echo "ERROR: not allowed input file to be empty!" 1>&2
exit 1
}
while getopts l:i: OPT; do
case $OPT in
l ) KEY_LIST="$OPTARG"
;;
i ) KEY_LIST_FILE="$OPTARG"
;;
\? ) usage_exit
;;
esac
done
shift $((OPTIND - 1))
if [ -z "$KEY_LIST" ] && [ -z "$KEY_LIST_FILE" ]; then
noarg_err
elif [ -n "$KEY_LIST" ] && [ -n "$KEY_LIST_FILE" ]; then
selecteither_err
elif [ -z "$1" ]; then
noinputfile_err
fi
echo "FILE: $1, KEY_LIST: ${KEY_LIST}, KEY_LIST(FILE): ${KEY_LIST_FILE}"
if [ -n "$KEY_LIST" ]; then
PARR=($(echo "${KEY_LIST}" | tr ',' ' '))
for p in "${PARR[@]}"; do
awk -F"," '
$1 ~ /'"$p"'/ { last_macthed = $0; }
END { print last_macthed ? last_macthed : "'"$p"'?,#N/A,#N/A,#N/A"; }
' $1
done
elif [ -n "$KEY_LIST_FILE" ] && [ -f "$KEY_LIST_FILE" ]; then
#👇①...☆今回修正する部分
cat "$KEY_LIST_FILE" | while read KEY || [ -n "${KEY}" ]; do
K=($(echo "${KEY}" | awk -F",{1}" '{k1=$1?$1:"NULL";k2=$2?$2:"NULL";k3=$3?$3:"NULL";k4=$4?$4:"NULL";print k1,k2,k3,k4;}'))
#👇でもキーワードの抽出が可能
#K=($(echo "${KEY}" | tr , '\n' | sed -r 's,^$,NULL,' | tr '\n' ' '))
echo "+++ MATCHING-KEYS 1: ${K[0]} 2: ${K[1]} 3: ${K[2]} 4: ${K[3]} +++ "
awk -F"," '
function isSkip(s_){return s_ == "NULL";}
{
ch1 = !isSkip("'"${K[0]}"'");
ch2 = !isSkip("'"${K[1]}"'");
ch3 = !isSkip("'"${K[2]}"'");
ch4 = !isSkip("'"${K[3]}"'");
total = ch1 + ch2 + ch3 + ch4;
if (ch1 && $1 !~ /'"${K[0]}"'/) {ch1=0}
if (ch2 && $2 !~ /'"${K[1]}"'/) {ch2=0}
if (ch3 && $3 !~ /'"${K[2]}"'/) {ch3=0}
if (ch4 && $4 !~ /'"${K[3]}"'/) {ch4=0}
if (ch1 + ch2 + ch3 + ch4 == total) {print $0}
}
' $1
done
fi
K[0] ~ K[3]
isSkip
$ ./simple_finder.sh -i search_list.csv employee.csv
+++ MATCHING-KEYS 1: 山田 2: 製造 3: NULL 4: NULL +++
+++ MATCHING-KEYS 1: 子 2: NULL 3: 名古屋 4: NULL +++
島田フガ子,経理部,名古屋支部,15年
+++ MATCHING-KEYS 1: モフ雄 2: NULL 3: NULL 4: 16年 +++
田頭モフ雄,営業部,名古屋支部,16年
+++ MATCHING-KEYS 1: 川 2: 製造 3: NULL 4: 14年 +++
亀川ヲル士,製造部,山口工場,14年
おまけ〜キーリストの直接入力検索もターゲット列を変更できるようにする
$ ./simple_finder.sh -l 経理,海外 -t 2 employee.csv
経理部の項目...
.....
海外部の項目...
.....
#!/bin/bash
usage_exit() {
echo "USAGE: $(basename $0) [-l key_list] [-t column_number] [-h help] [input_file]" 1>&2
exit 1
}
noarg_err() {
echo "ERROR: must provide key_list!" 1>&2
exit 1
}
selecteither_err() {
echo "ERROR: should select an option from -l/-i!" 1>&2
exit 1
}
noinputfile_err() {
echo "ERROR: not allowed input file to be empty!" 1>&2
exit 1
}
while getopts l:t:i: OPT; do
case $OPT in
l ) KEY_LIST="$OPTARG"
;;
t ) TARGET_COLUMN="$OPTARG"
;;
i ) KEY_LIST_FILE="$OPTARG"
;;
\? ) usage_exit
;;
esac
done
shift $((OPTIND - 1))
if [ -z "$KEY_LIST" ] && [ -z "$KEY_LIST_FILE" ]; then
noarg_err
elif [ -n "$KEY_LIST" ] && [ -n "$KEY_LIST_FILE" ]; then
selecteither_err
elif [ -z "$1" ]; then
noinputfile_err
fi
if [ -z "$TARGET_COLUMN" ]; then
TARGET_COLUMN=1
fi
echo "FILE: $1, KEY_LIST: ${KEY_LIST}, KEY_LIST(FILE): ${KEY_LIST_FILE}"
if [ -n "$KEY_LIST" ]; then
PARR=($(echo "${KEY_LIST}" | tr ',' ' '))
for p in "${PARR[@]}"; do
echo "+++ MATCHING-KEYS: $p @ column #$TARGET_COLUMN +++"
awk -F"," '
$'"$TARGET_COLUMN"' ~ /'"$p"'/ {
last_macthed = last_macthed ? last_macthed "\n" $0 : $0;
}
END {
switch_num='"$TARGET_COLUMN"';
if (switch_num==1) {
err_res="'"$p"'?,#N/A,#N/A,#N/A";
} else if (switch_num==2) {
err_res="#N/A,'"$p"'?,#N/A,#N/A";
} else if (switch_num==3) {
err_res="#N/A,#N/A,'"$p"'?,#N/A";
} else if (switch_num==4) {
err_res="#N/A,#N/A,#N/A,'"$p"'?";
}
print last_macthed ? last_macthed : err_res;
}
' $1
done
elif [ -n "$KEY_LIST_FILE" ] && [ -f "$KEY_LIST_FILE" ]; then
cat "$KEY_LIST_FILE" | while read KEY || [ -n "${KEY}" ]; do
K=($(echo "${KEY}" | awk -F",{1}" '{k1=$1?$1:"NULL";k2=$2?$2:"NULL";k3=$3?$3:"NULL";k4=$4?$4:"NULL";print k1,k2,k3,k4;}'))
#👇でもキーワードの抽出が可能
#K=($(echo "${KEY}" | tr , '\n' | sed -r 's,^$,NULL,' | tr '\n' ' '))
echo "+++ MATCHING-KEYS 1: ${K[0]} 2: ${K[1]} 3: ${K[2]} 4: ${K[3]} +++"
awk -F"," '
function isSkip(s_){return s_ == "NULL";}
{
ch1 = !isSkip("'"${K[0]}"'");
ch2 = !isSkip("'"${K[1]}"'");
ch3 = !isSkip("'"${K[2]}"'");
ch4 = !isSkip("'"${K[3]}"'");
total = ch1 + ch2 + ch3 + ch4;
if (ch1 && $1 !~ /'"${K[0]}"'/) {ch1=0}
if (ch2 && $2 !~ /'"${K[1]}"'/) {ch2=0}
if (ch3 && $3 !~ /'"${K[2]}"'/) {ch3=0}
if (ch4 && $4 !~ /'"${K[3]}"'/) {ch4=0}
if (ch1 + ch2 + ch3 + ch4 == total) {print $0}
}
' $1
done
fi
$ ./simple_finder.sh -l 経理,海外 -t 2 employee.csv
FILE: employee.csv, KEY_LIST: 経理,海外, KEY_LIST(FILE):
+++ MATCHING-KEYS: 経理 @ column #2 +++
島田フガ子,経理部,名古屋支部,15年
梅岡ボル伍,経理部,本社,25年
+++ MATCHING-KEYS: 海外 @ column #2 +++
銭形ガメ吉,海外部,メキシコ支部,11年
蒲田ウオ奈,海外部,メキシコ支部,9年
まとめ
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー