クライアントがライブMQTTストリームからデータをフィルタリングし、ファイルにデータを書き込むようにしましたmyfile.csv
。以下は最後の4行です。
1426134425,m,NWRL,MSV,001,d,SVlts,139,1840343,26089,28529,15987
1426134444,m,NWRL,MSV,001,d,status,139,1859000,23911,-33.836465,151.051189
1426134834,m,gf,TMX6BP,075,d,SVlts,216,1243746,27209,27409,17106
1426134845,m,gf,TMX6BP,075,d,status,216,1254000,179583,-33.836465,151.051189
この文書は常に更新されます。そのため、csvファイルの最後の行は引き続き変更されますが、フォーマットは変わりません。
尋ねる:myfile.csv
7番目の値が "SVlts"の代わりに "status"のbashを使用してファイルの最後の行をどのように読み取ることができますか?この内容を読んだ後、4番目、5番目、10番目の値を3つの異なる変数にどのように割り当てますか?この値をプッシュしてMySQLテーブルを更新します。
したがって、出力は次のようになります。
variable_1=TMX6BP
variable_2=075
variable_3=179583
前述のように、これら3つの変数は、次の行が印刷されるまでMySQLテーブル(自己更新が必要です)を更新するためにプッシュ/転送されますmyfile.csv
。そしてこれは繰り返し起こります。
答え1
これにより、最後の行で目的の情報がキャプチャされますfile
。
$ IFS=, read -r a b c var_1 var_2 d e f h var_3 extra < <(tail -n1 file)
$ echo $var_1 $var_2 $var_3
TMX6BP 075 179583
どのように動作しますか?
IFS=,
これにより、フィールド区切り文字が一時的にコンマに設定されます。
read -r a b c var_1 var_2 d e f h var_3 extra
これにより、フィールドがリストされた変数として読み込まれます。希望の名前を選択できます。
上記では、最初のフィールドはシェル変数に割り当てられ、2番目の
a
フィールドはに割り当てられますb
。それ以降に残ったものはすべてvar_3
シェル変数に割り当てられますextra
。< <(tail -n1 file)
file
これはコマンドの標準入力として最後の行を提供しますread
。 1 つ目は、<
リダイレクトに使用されるシェル記号です。この構成を<(...)
プロセス置換と呼びます。最初と2番目の間隔は次<
のとおりです。基本的な。
答え2
短い答え:
# tail -F: output appended data as the file grows
# Capital F to follow even if the file is reset to zero, recreated, etc.
# awk -F, sets FS - Field Separator to a comma
# Inside awk: See if field 7 == "status" and print fields 4, 5 and 10
tail -F myfile.csv | awk -F, '$7 == "status" { print $4, $5, $10 }'
データベースの更新方法を書いていないので、始めるのに役立つものを書いてみましょう。
私が理解したところによれば、myfile.csvファイルを編集せずに、更新スクリプト/タスクへの入力と呼ばれる3つの変数を使用します。エラー確認などは皆様にお任せいたします。
まず、MySQL データベースを更新するスクリプトを作成します。ここではただ笑います。
#!/bin/bash
# update-MySQL-table.sh
# redirecting stderr to stdout so awk will see it.
# Not much use with "echo", but ...
echo $0 $1 $2 $3 2>&1
次に、CSVファイルを読み取り、解析し、データベース更新スクリプトを起動する別のスクリプトがあります。
#!/bin/bash
# parse-my-CSV-file.sh
csvfile="myfile.csv"
tail -n0 -F $csvfile | \
awk -F, '
$7 == "status" {
cmd=sprintf("./update-MySQL-table.sh %s %s %s",$4,$5,$10)
cmd | getline output
print output
}'
その後、解析スクリプトを起動したら、7番目のフィールドに「status」があるmyfile.csvに追加された新しい行がどのようにstdoutに印刷されるかを確認する必要があります。
答え3
私は次のことをします:
tail -n1 -f file |
perl -MDBI -F, -lane 'BEGIN{$d = DBI->connect(...)}
if ($F[6] eq "status") {
$d->do("INSERT INTO foo VALUES (?,?,?)", @F[3,4,9]);
}'