awk 또는 sed 형식의 가변 기간

awk 또는 sed 형식의 가변 기간

awk 및 sed 명령을 많이 시도했지만 파일 형식을 올바르게 지정할 수 없습니다. 주요 문제는 때로는 존재하고 때로는 존재하지 않는 열 중간에 추가 쉼표를 처리하는 것입니다.

csv 파일에서는 다음과 같습니다.

Num,Type,StartTime,Duration,Var1,Var2,Var3
1,Forward,9/11/2019 11:15,"15 h, 45 m",98.03,-1.38,-0.2
2,Forward,9/12/2019 13:00,"8 h, 21 m",97.84,-0.83,1.27
3,Forward,9/12/2019 21:30,"20 h, 30 m",99.06,-2.12,-1.64
4,Forward,9/14/2019 8:00,18 h,97.47,-0.84,0.07
5,Backward,9/30/2019 14:00,56 m,95.93,-0.17,1.26

다음과 같이 보여야 합니다.

Num,Type,StartTime,Duration,Var1,Var2,Var3
1,Forward,9/11/2019 11:15,15:45,98.03,-1.38,-0.2
2,Forward,9/12/2019 13:00,8:21,97.84,-0.83,1.27
3,Forward,9/12/2019 21:30,20:30,99.06,-2.12,-1.64
4,Forward,9/14/2019 8:00,18:00,97.47,-0.84,0.07
5,Backward,9/30/2019 14:00,0:56,95.93,-0.17,1.26

답변1

확인하는 방법은 다음과 같습니다.오직awk 스크립트를 사용하여 필수 필드 수정

BEGIN { FPAT = "([^,]+)|(\"[^\"]+\")"; OFS = "," }

function convert_time(timestr)
{
  gsub(/[" ]/, "", timestr);
  if (timestr !~ ",") {
    number = substr(timestr, 1, length(timestr) -1)
    if (timestr ~ "m$") return "0:" number
    if (timestr ~ "h$") return number ":00"
  } else {
    gsub(/[^0-9,]/,"", timestr)
    gsub(/,/,":", timestr)
    return timestr
  }
}

NR > 1 { $4 = convert_time($4) }

{ print $0 }

  • 사용하여FPAT일부 필드에 쉼표가 포함되어 있어도 awk에서 변수를 분할할 수 있습니다. 큰따옴표 안에 포함되어 있으면 됩니다.
  • 나는 그것을 사용하고 있다오르페우스수정된 행을 인쇄할 때 필드가 쉼표로 구분되도록 하려면 변수를 사용하세요.
  • 각 행(헤더라고 가정하는 첫 번째 행 제외)에서 convert_time요청에 따라 네 번째 필드를 변환하기 위해 작성한 함수를 사용합니다.
  • 마지막으로 수정된 줄을 인쇄합니다.

기능 convert_time: 먼저, 필드에 날짜도 포함되어 있으면 분과 시간만 있을 수 있다고 가정했습니다. 예를 들어 함수가 제대로 작동하지 않아 그에 따라 수정해야 합니다.

  • 나는 gsub변수에서 공백이나 따옴표를 제거하는 데 사용합니다 timestr.
  • 쉼표가 포함되어 있지 않으면 timestr분 또는 시간이라는 항목이 하나만 있다는 의미입니다.
    • 마지막 문자를 제거하는 함수를 사용하여 숫자만 얻습니다 substr.
    • 변수의 마지막 문자 timestr가 m(분)이면 00:number가 반환됩니다.
    • 변수의 마지막 문자 timestr가 h(시간)이면 숫자: 00이 반환됩니다.
  • 쉼표가 포함된 경우 timestr첫 번째 숫자는 시, 두 번째 숫자는 분이라고 가정합니다.
    • 나는 gsub숫자나 쉼표가 아닌 모든 문자를 제거하는 데 사용합니다. 이렇게 하면 h 및 m 문자가 제거되고 숫자와 쉼표만 남습니다.
    • 그런 다음 다시 gsub.

전체 스크립트를 이라는 파일에 넣은 convert_time.awk다음 실행했습니다.

산출:

$ cat file.csv | awk -f convert_time.awk
Num,Type,StartTime,Duration,Var1,Var2,Var3
1,Forward,9/11/2019 11:15,15:45,98.03,-1.38,-0.2
2,Forward,9/12/2019 13:00,8:21,97.84,-0.83,1.27
3,Forward,9/12/2019 21:30,20:30,99.06,-2.12,-1.64
4,Forward,9/14/2019 8:00,18:00,97.47,-0.84,0.07
5,Backward,9/30/2019 14:00,0:56,95.93,-0.17,1.26

이 경우 특정 필드(4번째 필드)만 수정됩니다.

답변2

 sed 's/"//g' kl| awk '!/m/{gsub("h,","h,00 m,",$0)}1'| sed "s/h,/:/g"| sed "s/m,/,/g"|sed  -r "s/\s+:\s+/:/g"

산출

1,Forward,9/11/2019 11:15,15:45 ,98.03,-1.38,-0.2
2,Forward,9/12/2019 13:00,8:21 ,97.84,-0.83,1.27
3,Forward,9/12/2019 21:30,20:30 ,99.06,-2.12,-1.64
4,Forward,9/14/2019 8:00,18 :00 ,97.47,-0.84,0.07
5,Backward,9/30/2019 14:00,56 ,95.93,-0.17,1.26

관련 정보