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번 열만 ( )로 이름을 변경 Info하고 5번 열의 이름을 ( )로 변경합니다.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개 열로 줄입니다.

관련 정보