新しいデータを取得してmysqlテーブルにアップロードする方法、

新しいデータを取得してmysqlテーブルにアップロードする方法、

金髪の瞬間を過ごしていました。

問題の説明: したがって、ファイルにランダムな間隔で継続的に更新されるタイムスタンプを持つデータがあり、以前の合計時間のデータをフィルタリングしたいと思います(つまり、現在の時刻が14:35の場合は13時の期間を意味します。) 14:00、同様に時間が00:03の場合、23:00~00:00です。このデータを取得したら、それをmysqlテーブルに送信したいと思います。完了すると、crontabを使用して自動的に実行されます。

私が達成したいもの: 理想的には、過去のデータを取得してmysqlテーブルに送信したいと思います。その時間に何もない場合は、「この間は更新がありません」というメッセージを送信したいと思います。したがって、本質的にこれはif / elseステートメントだと思います。新しいものがある場合はこれを行い、そうでない場合は更新しないでください。しかし、これはうまくいきません。

私の考えで何が起こっているのか: コードは過去の合計時間を確認し、それをmysqlテーブルに送信します。しかし、他の記録もすべて確認しますが、古い記録は過去1時間以内ではないため、「その他」カテゴリに入り、「この期間中は更新がありません」というメッセージがたくさん出てきます。尋ねる:どうすればこれ以上行くことができますか?

私のコードは次のとおりです(いくつかの項目を削除したため、構文上正確ではない可能性があります)。

#!/bin/bash
#---------------------------------------------------------------------------------
#   Adds all the transactions for the past full hour into a log file
#   named log.csv
#   input file:     mqtt.csv
#   output file:    outfile.csv
#
#
#
#---------------------------------------------------------------------------------

current_time_hr=`date +%H`      #Get the current hour only
current_time_date=`date +%F`    #Get the full date YYYY-MM-DD
current_time_full=$current_time_date' '$current_time_hr':00:00'  #Concatenate the date & current hour
current_time=`date -d "$current_time_full" +%s`     #convert the time to seconds
echo "$current_time"                    #Print out
period=3600                                     #3600 seconds = 60 min = 1 hour
one_hr_before=$((current_time-period))    # subtrace one hour in seconds - to get one hour ago in seoonds 
echo $one_hr_before                     #Print out

count=0                             #Initialize the counteR
log=log.txt
out_file_name=outfile.csv               #Output file

`rm -f $out_file_name`              #Rmv to avoid appending

#Filter below
cat /DIR/SOME_DIR/mqtt.csv | grep SX | grep ',scan' | grep -v 'HDCU.*HDCU' | grep -v 'Sensor,Module' | grep '^[0-9]*,e,gf,STACKEXCHANGEe,HDCU.*,d,scan,.*,.*,.*,.*,.*,.*' | sed 's/,H[0-9][0-9]/,/g' | tail -n100  >>$out_file_name

cat $out_file_name | ( while read line
do
    echo $line    #Print out

    #-----
    # This is to convert $line into an array named "awk_var_array"
    #----- ----- ----- ----- ----- ---------- ----- ---------- ----- -----
    IFS="," 
    read -a awk_var_array <<< "${line}"

    record_time=${awk_var_array[0]}
    container=${awk_var_array[4]}   
    time_date=`date -d "@$record_time" +%F`' '`date -d "@$record_time" +%T`

    no_array_less_one=$((${#awk_var_array[@]}-2))

    #-----------
    # Var is created & initialized; And is used to concatenate machine name parts 
    # in the consequtive fields before direction (IN/OUT) field
    #---------- 
        var=""
    k=$((${#awk_var_array[@]}-1)) # k is the last element of the array
    j=11                  # j is the element where the part name  starts
    while [ $j -lt $k ]       # do a for a loop with while
    do
        echo "j:$j k:$k  ${awk_var_array[$j]}" 
        new_var=${awk_var_array[$j]}
                var=$var' '$new_var

        j=$((j+1))

    done
    part_name=${var:1} #gets rid of the first character as this is a ' ';

    echo -e  "\t\t\t\t\t\t\tvar $part_name"

        count=$((count+1))   #Increase counter

        echo "c-o-u-n-t $count"   #Print out

    full_date=`date -d "@$record_time" +%F`' '`date -d "@$record_time" +%T`
    echo "FD:$full_date"
    scan_id=${awk_var_array[9]}
    dir=${awk_var_array[$k]}
    dir=`echo $dir | sed 's/*//g'`
    echo "FD:$full_date, SID:$scan_id, PartName:$part_name, DIR:$dir"

  if [ "$record_time" -lt "$current_time" ] && [ "$record_time" -ge "$one_hr_before" ]   #Bouncries for permissible data count
    then

        dbq="INSERT INTO mytable.table (time, part_number, direction, stock_point_name, scan_id, ignored) VALUES ('$time_date', '$part_name', '$dir', '$container', '$scan_id', '0');"

    else


        dbq="INSERT INTO mytable.table (part_number) VALUES ('there is no updates this hour');"

    fi

mysql -uUSER -p'PASSWORD' << EOF
$dbq
EOF


done


echo "count: $count"            #Print out
time_stamp_date=`date +%F`  #Get date
time_stamp_time=`date +%T`  #Get time
time_stamp=$time_stamp_date' '$time_stamp_time  #Concatenate current DATE TIME then print out to log.csv file
printf "%20s;%8d;records added\n"  "$time_stamp" "$count" >>$log )

答え1

ロジックを少し更新し、ループ内に実際に追加された行数を数えるだけです。データが追加されない場合は、ループの外側に「何もしない」メッセージを追加します。

これは擬似コードです:

counter = 0
for each line
  if date in range
    insert data
    increment counter
  else
    # do nothing
  fi
done
if counter > 0
  # some lines were imported, nothing more to do
else
  insert 'no updates' message
fi

各行に対して新しいデータベース接続を開くことは非常に非効率的です。かなり大きなデータブロックを取得する必要がある場合は、コードをさらにリファクタリングする必要があります。つまり、メインループで.sqlすべての挿入ステートメントを含むファイルをビルドし、ループの直後(理想的にはトランザクション内で)を実行します。または、挿入を生成しないで、適切な形式でデータを生成します。LOAD DATA INFILE

関連情報