カテゴリー
[Awk & Jq活用] シェルコマンドで複数の条件による検索し結果をCSVで返す
※ 当ページには【広告/PR】を含む場合があります。
2021/03/24
はじめに
検索の基礎
Awkの場合
match
用法:
match(<対象文字列>, <検索する文字パターン>)
<検索する文字パターン>
RSTART:
match関数で一致した文字列の開始位置を格納。
一致しなかった場合は0が設定される
RLENGTH:
match関数で一致した文字列の長さを格納。
一致しなかった場合は-1が設定される
$ awk -F"," '{
num = match($3, /(山田|.?郎)/);
print RSTART " " RLENGTH;
print $0 " -> " $3 "が" num "バイト目に見つかりました";
}' << EOF
2021/04/06,出張,山田 モフ男
2021/04/08,会議,佐藤 ピヨ子
2021/04/17,リモートワーク,鈴木 フガ郎
EOF
#👇出力
1 6
2021/04/06,出張,山田 モフ男 -> 山田 モフ男が1バイト目に見つかりました
0 -1
2021/04/08,会議,佐藤 ピヨ子 -> 佐藤 ピヨ子が0バイト目に見つかりました
11 6
2021/04/17,リモートワーク,鈴木 フガ郎 -> 鈴木 フガ郎が11バイト目に見つかりました
Jqの場合
to_entries
key-value
$ jq -sR '
[ split("\n")[] | select(length > 0) | split(",") ]
#👇配列をkey-valueパターンに展開
| to_entries
#👇indexも含めたオプジェクトとして再構築
| map({date: .value[0], task: .value[1], name: .value[2], index: .key})
#👇csvの3列目(氏名)の中身で検索
| map(select(.name | test("(山田|.?郎)")))
' << EOF
2021/04/06,出張,山田 モフ男
2021/04/08,会議,佐藤 ピヨ子
2021/04/17,リモートワーク,鈴木 フガ郎
EOF
#👇出力
[
{
"date": "2021/04/06",
"task": "出張",
"name": "山田 モフ男",
"index": 0
},
{
"date": "2021/04/17",
"task": "リモートワーク",
"name": "鈴木 フガ郎",
"index": 2
}
]
応用課題 ~ 複数条件を指定
keywords.csv
$ cat << EOF > keywords.csv
都,市
道,区
府,町
県,村
EOF
cities.csv
$ cat << EOF > cities.csv
大阪府門真市
山形県新庄市
沖縄県与那国町
奈良県十津川村
北海道倶知安町
山梨県南アルプス市
東京都港区
大分県豊後高田市
EOF
Awkの場合
PARR=($(awk -F"," '{ arr = arr " " $1;} END{print arr;}' keywords.csv))
SARR=($(awk -F"," '{ arr = arr " " $2;} END{print arr;}' keywords.csv))
for p in "${PARR[@]}"; do
for s in "${SARR[@]}"; do
awk -F "," '
{
s_pos1 = match($0, /'"$p"'/);
s_pos2 = match($0, /'"$s"'/);
if (s_pos1 > 0 && s_pos2 > 0) {
print $0 " -> '"$p"'が" s_pos1 "バイト目と'"$s"'が" s_pos2 "バイト目に見つかりました";
}
}
' cities.csv
done
done
#👇出力
東京都港区 -> 都が7バイト目と区が13バイト目に見つかりました
北海道倶知安町 -> 道が7バイト目と町が19バイト目に見つかりました
大阪府門真市 -> 府が7バイト目と市が16バイト目に見つかりました
山形県新庄市 -> 県が7バイト目と市が16バイト目に見つかりました
山梨県南アルプス市 -> 県が7バイト目と市が25バイト目に見つかりました
大分県豊後高田市 -> 県が7バイト目と市が22バイト目に見つかりました
沖縄県与那国町 -> 県が7バイト目と町が19バイト目に見つかりました
奈良県十津川村 -> 県が7バイト目と村が19バイト目に見つかりました
/.../の中身
$"<変数名>"
'...'(複数のシングルコーテーションで囲うこと)
PARR
SARR
Jqの場合
$"<変数名>"
P_LOOP=$(jq -sR '[ split("\n")[] | select(length > 0) | split(",") ] | map(.[0]) | .[]' keywords.csv)
S_LOOP=$(jq -sR '[ split("\n")[] | select(length > 0) | split(",") ] | map(.[1]) | .[]' keywords.csv)
for p in $P_LOOP; do
for s in $S_LOOP; do
jq -sR '
[ split("\n")[] | select(length > 0) | split(",") ]
| to_entries
| map({city: .value[0], index: .key})
| map({city_p: (.city | match("'"${p//\"/}"'"; "g")), index, city})
| map({city_s: (.city | match("'"${s//\"/}"'"; "g")), city_p, index, city})
| select(length > 0)[]
' cities.csv
done
done
#👇出力
{
"city_s": {
"offset": 4,
"length": 1,
"string": "区",
"captures": []
},
"city_p": {
"offset": 2,
"length": 1,
"string": "都",
"captures": []
},
"index": 6,
"city": "東京都港区"
}
{
"city_s": {
"offset": 6,
"length": 1,
"string": "町",
"captures": []
},
"city_p": {
"offset": 2,
"length": 1,
"string": "道",
"captures": []
},
"index": 4,
"city": "北海道倶知安町"
}
{
"city_s": {
"offset": 5,
"length": 1,
"string": "市",
"captures": []
},
"city_p": {
"offset": 2,
"length": 1,
"string": "府",
"captures": []
},
"index": 0,
"city": "大阪府門真市"
}
{
"city_s": {
"offset": 5,
"length": 1,
"string": "市",
"captures": []
},
"city_p": {
"offset": 2,
"length": 1,
"string": "県",
"captures": []
},
"index": 1,
"city": "山形県新庄市"
}
{
"city_s": {
"offset": 8,
"length": 1,
"string": "市",
"captures": []
},
"city_p": {
"offset": 2,
"length": 1,
"string": "県",
"captures": []
},
"index": 5,
"city": "山梨県南アルプス市"
}
{
"city_s": {
"offset": 7,
"length": 1,
"string": "市",
"captures": []
},
"city_p": {
"offset": 2,
"length": 1,
"string": "県",
"captures": []
},
"index": 7,
"city": "大分県豊後高田市"
}
{
"city_s": {
"offset": 6,
"length": 1,
"string": "町",
"captures": []
},
"city_p": {
"offset": 2,
"length": 1,
"string": "県",
"captures": []
},
"index": 2,
"city": "沖縄県与那国町"
}
{
"city_s": {
"offset": 6,
"length": 1,
"string": "村",
"captures": []
},
"city_p": {
"offset": 2,
"length": 1,
"string": "県",
"captures": []
},
"index": 3,
"city": "奈良県十津川村"
}
map({city_p: (.city | match("'"${p//\"/}"'"; "g")),...})
まとめ
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー