如何根据文件名的一部分创建文件夹以及使用 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 中),例如 filename 是Thaban_TD_xxxxxx_Forms1.csv并且想要创建一个名为xxxxxx_date.在当前形式中,上面的代码创建文件夹,其名称基于完整的 csv 文件名。长度xxxxxx不同,但文件名格式始终相同。

  2. 我还想提取时间戳、数据 2、数据 4 列,将“数据 2”重命名为“信息”,将“数据 4”重命名为“输出”,然后将信息和输出列中的数据四舍五入为 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"

    仅将第一行的column#3 重命名为Info并将column#5 重命名为( )OutputNR==1

  • 更新hdr=$1 FS $3 FS $5

    对于标题行,我们只需要列 #1、#3 和 #5(FSF字段S分隔符,这就是我们在 中定义的内容-F,

  • 更新printf("%s%s,%.3f,%.3f\n", hdr ORS, $1, $3, $5)

    输出第 3 列和第 5 列,保留 3 位小数%.3f

  • 更新print hdr ORS x ",0,0"

    减少到仅输出 3 列。

相关内容