最新のタイムスタンプデータに基づいて新しいCSVファイルを作成します。

最新のタイムスタンプデータに基づいて新しいCSVファイルを作成します。

複数のdatファイルにアクセスし、前日のデータに基づいてcsvファイルを生成するスクリプトがあります。これらのDATファイルは、さまざまなデバイスのデータに基づいて毎分更新されます。

スクリプトの断片:

gawk -F, '

{ gsub(/"/,"") }

FNR==2{ 
        delete timestamp;                                     #This code was added
        start=strftime("%Y %m %d 00 00 00", systime()-172800);#to fix the
        for(min=0; min<1440; min++)                           #timestamp formatting
        timestamp[strftime("%F %H:%M", mktime(start)+min*60)] #issue from the input files.
     
        fname=FILENAME; 
        gsub(/Real_|_Table2.*\.dat$/,"", fname);

        $2="col1";
        $3="col2";
        $4="col3";
        $5="col4";
        
        if ( fname=="file1")        ID1="01";   
        else if ( fname=="file2")   ID1="02";
        else if ( fname=="file3")   ID1="03";
        else ID1="00";      
    
        hdr=$1 FS $2 FS $3 FS $4 FS $5;
         
        yday=strftime("%Y%m%d", systime()-86400);
        dirName=yday;
        system("mkdir -p "dirName); next
     }

(substr($1,1,16) in  timestamp){

        fname=FILENAME; 
        gsub(/Real_|_Table2.*\.dat$/,"", fname);

               cp=$1; gsub(/[-: ]|00$/, "", cp);
         if ( fname=="file2"|| fname=="file3")

         printf("%s%s,%.3f,%.3f,%.3f,%.3f\n", hdr ORS, $1, $3, $2, $4, $6)>(dirName"/"ID1"_"fname"_"cp".csv");
        else 
        printf("%s%s,%.3f,%.3f,%.3f,%.3f\n", hdr ORS, $1, $3, $5, "999")>(dirName"/"ID1"_"fname"_"cp".csv");

       close(dirName"/"ID1"_"fname"_"cp".csv");
       delete  timestamp[substr($1,1,16)] }

ENDFILE{ for (x in  timestamp){
             cpx=x; gsub(/[-: ]/, "", cpx);
             print hdr ORS x "-999,-999,-999,-999," >(dirName"/"ID1"_"fname"_"cpx".csv");
             
             close(dirName"/"ID1"_"fname"_"cpx".csv")
     }
}' *_Table2.dat 


datファイルから新しいデータを取得し、新しいデータのcsvファイルのみを生成するようにスクリプトを編集したいと思います。現在の形式では、スクリプトは* .datファイル(新しいファイルまたは履歴ファイル)の各タイムスタンプに対してcsvファイルを生成します。

入力ファイルの例(Real_file1_table2.dat):

"Data for Site1"
TIMESTAMP,col1,col2,col3,col4
"2023-11-30 11:00:00",289233,0.3495333,0.2412115,333.2676
"2023-11-30 11:01:00",289234,1.035533,1.019842,344.1969

タイトルは2行目です。 次に、次の出力ファイルを作成します。

01_file1_202311301100.csv

01_file1_202311301101.csv

など..

csvファイルに含まれるデータはタイムスタンプに基づいています。

たとえば、

01_file1_202311301100.csv次のデータが含まれています。

TIMESTAMP,col1,col2,col3,col4
2023/11/30 11:00,289233,0.349,0.241,333.267

01_file1_202311301101.csv次のデータが含まれています。

TIMESTAMP,col1,col2,col3,col4
2023/11/30 11:01,289234,1.035,1.019,344.196

など。

このcsvファイルのデータは3つの浮動小数点に丸められます。

スクリプトが2番目に実行されると、次のデータがReal_file1_table2.dat:

"Data for Site1"
TIMESTAMP,col1,col2,col3,col4
"2023-11-30 11:00:00",289233,0.3495333,0.2412115,333.2676
"2023-11-30 11:01:00",289234,1.035533,1.019842,344.1969
"2023-11-30 11:02:00",289235,0.7758334,0.7252186,17.75404
"2023-11-30 11:03:00",289236,0.7693,0.7103683,359.0702

スクリプトから最新のデータに対してのみcsvファイルを生成したいと思います。つまり:

01_file1_202311301102.csv

01_file1_202311301103.csv

すでに存在するcsvファイルを再作成したくありません。

したがって、スクリプトが実行されるたびに、最新のデータに対してのみcsvファイルを生成する必要があります。

ご協力ありがとうございます

ベストアンサー1

仮定:

  • 名前付き出力ファイルの場合、01_file1_202311301100.csv文字列は'file1'入力ファイル名の2番目の「_」区切りフィールドから始まりますReal_file1_table2.dat
  • OPのコードは、「昨日」の新しいサブディレクトリを作成しているように見えますが、これはこの回答のために日付が「今日」の入力ファイルエントリを処理しないことを意味します。 /outputファイルは現在のディレクトリにあります。 Medium; OPがサブディレクトリを処理し、「昨日」と「今日」を処理する方法をコードに拡張できますか?
  • 二重引用符で囲まれた唯一の入力フィールドは、最初の(カンマ区切り)フィールドです。
  • 最初のフィールドは常にformatです"YYYY-MM-DD HH:MM:SS"。それ以外の場合は、その行を無視します。
  • 改行を含む入力フィールドはありません。

全体的な設計:

  • bash出力ファイルのプレフィックス()を決定しますpfx(入力ファイル名に基づいて)。
  • bash「最後」出力ファイルの名前を決定します。
  • pfx「最後」の出力ファイル名を次に渡します。awk
  • awk入力*.datファイル処理用
  • 最初のフィールドの内容に基づいて出力ファイル名を設定します(例:2023-11-30 11:00:00goes 202311301100)。
  • 出力ファイル名が次の場合未満「最後の」出力ファイル名は、出力ファイルがすでに存在することを示すため、入力行を無視します。
  • 出力ファイル名が次の場合同じ「最後の」出力ファイル名を使用すると、新しい出力ファイルの作成が続行されます(これにより、スクリプトの実行2023-11-30 11:00前後にファイルに日付/時刻値を追加することが解決されます。例: -*.datawk
  • 出力ファイル名が次の場合より良い「最後」の出力ファイル名は、新しい出力ファイルを生成する必要があることを示します。

離れてbash / awkいる:

for datfile in *_table2.dat
do
    [[ ! -f "${datfile}" ]] && break

    ############
    #### the following bash code needs to be run before each run of the awk script

    IFS='_' read -r _ pfx _ <<< "${datfile}"

    case "${pfx}" in
        file1)  pfx="01_${pfx}" ;;
        file2)  pfx="02_${pfx}" ;;    
        file3)  pfx="03_${pfx}" ;;
            *)  pfx="00_${pfx}" ;;
    esac

    last_file="${pfx}_000000000000.csv"

    for outfile in "${pfx}"_*.csv
    do
        [[ -f "${outfile}" ]] && last_file="${outfile}"
    done

    ############
    #### at this point we have:
    ####   1) the '##_file#' prefix for our new output files(s)
    ####   2) the name of the 'last' output file

    awk -v pfx="${pfx}" -v last_file="${last_file}" '
    BEGIN      { FS=OFS=","
                 regex = "^\"[0-9]{4}.*\"$"                               # 1st field regex: "YYYY..."
               }

    FNR==2     { hdr = $0 }

    $1 ~ regex { dt = $1                                                    # copy 1st field
                 gsub(/[^[:digit:]]/,"",dt)                               # strip out everything other than digits
                 dt = substr(dt,1,12)                                     # grab YYYY-MM-DD HH:MM which now looks like YYYYMMDDHHMM

                 if ( dt != dt_prev ) {                                   # if this is a new dt value
                    dt_prev = dt
                    printme = 1                                           # default to printing input lines to new output file

                    close(outfile)                                        # close previous output file
                    outfile = pfx "_" dt ".csv"                           # build new output file name

                    if ( outfile < last_file ) {                          # if "less than" last file then we will skip
                       printf "WARNING: file exists: %s (skipping)\n", outfile
                       printme = 0
                    }
                    else
                    if ( outfile == last_file ) {                         # if "equal to" last file then overwrite
                       printf "WARNING: file exists: %s (overwriting)\n", outfile
                       print hdr > outfile                                # print default header to our overwrite file
                    }
                    else                                                  # else new output file is "greater than" last file
                       print hdr > outfile                                # print default header to our new output file
                 }

                 if ( printme ) {                                         # if printme==1 then print current line to outfile
                    print $1,$2,sprintf("%0.3f%s%0.3f%s%0.3f",$3,OFS,$4,OFS,$5) > outfile
                 }
               }
    ' "${datfile}"
done

OPの最初のバージョンに対して実行Real_file1_table2.dat

$ awk ....

$ head 01*csv
==> 01_file1_202311301100.csv <==
Timestamp,col1,col2,col3,col4
"2023-11-30 11:00:00",289233,0.3495333,0.2412115,333.2676

==> 01_file1_202311301101.csv <==
Timestamp,col1,col2,col3,col4
"2023-11-30 11:01:00",289234,1.035533,1.019842,344.1969

Real_file1_table2.dat「オーバーライド」ロジックをテストするために、OPの2番目のバージョンを次のように変更します。

$ cat Real_file1_table2.2.dat
Timestamp,col1,col2,col3,col4
"2023-11-30 11:00:00",289233,0.3495333,0.2412115,333.2676
"2023-11-30 11:01:00",289234,1.035533,1.019842,344.1969
"2023-11-30 11:01:00",666666,0.7777777,0.8888888,17.99999    # another 2023-11-30 11:01 entry
"2023-11-30 11:02:00",289235,0.7758334,0.7252186,17.75404
"2023-11-30 11:03:00",289236,0.7693,0.7103683,359.0702

この新しいバージョンに対して実行してくださいReal_file1_table2.dat

$ awk ...
WARNING: file exists: 01_file1_202311301100.csv (skipping)
WARNING: file exists: 01_file1_202311301101.csv (overwriting)

$ head 01*csv
==> 01_file1_202311301100.csv <==
Timestamp,col1,col2,col3,col4
"2023-11-30 11:00:00",289233,0.3495333,0.2412115,333.2676

==> 01_file1_202311301101.csv <==
"2023-11-30 11:01:00",289234,1.035533,1.019842,344.1969
"2023-11-30 11:01:00",666666,0.7777777,0.8888888,17.99999

==> 01_file1_202311301102.csv <==
Timestamp,col1,col2,col3,col4
"2023-11-30 11:02:00",289235,0.7758334,0.7252186,17.75404

==> 01_file1_202311301103.csv <==
Timestamp,col1,col2,col3,col4
"2023-11-30 11:03:00",289236,0.7693,0.7103683,359.0702

おすすめ記事