awkを使用してファイル名の一部に基づいてフォルダを作成し、特定の列を抽出して名前を変更する方法

awkを使用してファイル名の一部に基づいてフォルダを作成し、特定の列を抽出して名前を変更する方法

次のコードは、フォルダに含まれるcsvファイルからデータを抽出し、ファイル名と日付に基づいて新しいフォルダを作成し、そのフォルダに複数のcsvファイルを作成して保存します。これについて詳しくはこちらをご覧ください。CSVファイルを分割し、列に基づいて複数のCSVファイルを作成する方法

gawk -F, '
BEGIN{ start=strftime("%Y %m %d 00 00 00", systime()-86400);
       for(min=0; min<1440; min++)
           timestamp[strftime("%F %H:%M", mktime(start)+min*60)]
     }

{ gsub(/"/,"") }

FNR==1{
       hdr=$0; yday=strftime("%Y%m%d", systime()-86400);
       fname=FILENAME; sub(/.csv$/,"", fname); dirName=fname"_"yday;
       system("mkdir "dirName); next
     }

(substr($1,1,16) in  timestamp){
       cp=$1; gsub(/[-: ]|00$/, "", cp);
       print hdr ORS $0 >(dirName"/"cp".csv");
       close(dirName"/"cp".csv");
       delete  timestamp[substr($1,1,16)] }

ENDFILE{ for (x in  timestamp){
             cpx=x; gsub(/[-: ]/, "", cpx);
             print hdr ORS x ",0,0,0,0" >(dirName"/"cpx".csv");
             close(dirName"/"cpx".csv")
     }
}' multiple*.csv
  1. ファイル名の一部を使用して(awkで)フォルダを作成するThaban_TD_xxxxxx_Forms1.csvにはどうすればよいですかxxxxxx_date?現在の形式では、上記のコードは名前が完全なcsvファイル名に基づいてフォルダを作成します。長さはxxxxxx異なりますが、ファイル名の形式は常に同じです。

  2. また、タイムスタンプ、data2、data4列を抽出し、「data2」の名前を「info」に、「data4」の名前を「output」に変更し、infoおよび出力列のデータを小数点3桁に丸めようとします。同じコードで

入力ファイル:Thaban_TD_xxxxxx_Forms1.csv

TIMESTAMP,Data1,Data2,Data3,Data4
"2021-01-03 00:00:00",80953,3.243183,2.943338,358.0123
"2021-01-03 00:01:00",80954,2.173187,1.990327,344.5851
...
"2021-01-03 23:59:00",80957,4.04172,3.82053,355.5481
"2021-01-04 00:00:00",80955,3.700353,3.593842,346.2665
...
"2021-01-04 23:59:00",80956,3.125094,2.922542,350.9915
"2021-01-05 00:00:00",80957,4.04172,3.82053,355.5481
...
"2021-01-05 23:59:00",80956,3.125094,2.922542,350.9915
etc...

これが私が望む出力方法です。

202101030000.csv作成されたフォルダ内の出力ファイルxxxxxx_20210103

TIMESTAMP,Info,Output
2021-01-03 00:00:00,3.243,358.012

...

202101032359.csv作成されたフォルダ内の出力ファイルxxxxxx_20210103

TIMESTAMP,Info,Output
2021-01-03 23:59:00,4.042,355.548

答え1

gawk -F, '
{ gsub(/"/,"") }

FNR==1{
       delete timestamp;
       start=strftime("%Y %m %d 00 00 00", systime()-86400);
       for(min=0; min<1440; min++)
           timestamp[strftime("%F %H:%M", mktime(start)+min*60)]
       $3="Info"; $5="Output"; hdr=$1 FS $3 FS $5; 
       yday=strftime("%Y%m%d", systime()-86400);
       fname=FILENAME; gsub(/Thaban_TD_|_.*\.csv$/,"", fname); dirName=fname"_"yday;
       system("mkdir "dirName); next
     }

(substr($1,1,16) in  timestamp){
       cp=$1; gsub(/[-: ]|00$/, "", cp);
       printf("%s%s,%.3f,%.3f\n", hdr ORS, $1, $3, $5)>(dirName"/"cp".csv");
       close(dirName"/"cp".csv");
       delete  timestamp[substr($1,1,16)] }

ENDFILE{ for (x in  timestamp){
             cpx=x; gsub(/[-: ]/, "", cpx);
             print hdr ORS x ",0,0" >(dirName"/"cpx".csv");
             close(dirName"/"cpx".csv")
     }
}' multiple*.csv

ここで更新された内容は次のとおりです。

  • 修正するgsub(/Thaban_TD_|_.*\.csv$/,"", fname)

    ファイル名からThaban_TD_部分を削除します。_<anything>.csv

  • 次へ追加$3="Info"; $5="Output"

    最初の行の3列のみ()に名前を変更し、Info5列の名前を()に変更します。OutputNR==1

  • 修正するhdr=$1 FS $3 FS $5

    ヘッダー行の場合は、列#1、#3、#5のみが必要です(フィールド区切り記号FSはで定義されています)。FS-F,

  • 修正するprintf("%s%s,%.3f,%.3f\n", hdr ORS, $1, $3, $5)

    3列と5列を小数点以下3桁まで出力します%.3f

  • 修正するprint hdr ORS x ",0,0"

    出力を3列に減らします。

関連情報