Text-Processing

如何根據文件名的一部分創建文件夾並使用 awk 提取和重命名特定列

  • February 25, 2021

以下程式碼從文件夾中包含的 csv 文件中提取數據,創建新文件夾(基於文件名和日期),在所述文件夾中創建和儲存多個 csv 文件。更多資訊在這裡how-to-split-csv-file-and-create-multiple-csv-files-based-on-a-column

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. 我還想提取 Timestamp、Data2、Data4 列,將“Data2”重命名為“Info”,將“Data4”重命名為“Output”,然後將 Info 和 Output 列中的數據四捨五入為 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
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"

僅將第一行的第 3Info列和第 5列重命名Output為 ( NR==1)

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

對於標題行,我們只需要列 #1、#3 和 #5(FS是欄位F分隔S符,這就是我們在 中定義的-F,

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

輸出帶 3 個小數點的列 #3 和 #5 %.3f

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

減少到只輸出 3 列。

引用自:https://unix.stackexchange.com/questions/636194