형식이 지정된 ASCII 입력에서 CSV 파일 만들기

형식이 지정된 ASCII 입력에서 CSV 파일 만들기

저는 리눅스를 사용하고 있습니다.

다음 형식의 파일이 있습니다

; Header info
;--+-----+--+----+-+----------------
;Co TASK# ID PROP X Remarks
;de (full desc.)
;--+-----+--+----+-+----------------
AAA P00_1 000Lean - not yet done
AAB P00_2 11 Fat  X 20190606
AAC P00_3 1  MidleX canceled

이 형식의 csv 파일로 변환하고 싶습니다.

Code;Task#;ID;PROP;X;Remarks
AAA;P00_1;000;Lean;-;not yet done
AAB;P00_2;11;Fat;X;20190606
AAC;P00_3;1;Midle;X;canceled

필드 길이는 다양하지만 해당 "+" 열까지 가능합니다. 예를 들어 "AAC"로 시작하는 행과 "중간" 필드를 참조하세요.

첫 번째 단계는 헤더 형식 설명에서 "+" 기호가 있는 열을 식별하고 "중간"과 같은 "큰" 필드를 고려하여 각 행의 이러한 열에 ";"를 삽입하는 것입니다(위 참조).

Linux에서 이 목적을 달성하기 위해 awk 또는 sed 또는...를 사용하는 방법은 무엇입니까?

건배!

답변1

고정된 스키마가 있는 경우(이름을 지정했습니다 input-schema.csv)

column,start,length
Code,0,4
Task,4,6
ID,10,3
PROP,13,5
X,18,2
Remarks,20,17

당신은 그것을 사용할 수 있습니다csvkit그리고 실행합니다(name으로 지정한 입력 파일 사용 input.csv).

<input.csv grep -v '^;' | in2csv -f fixed -s input-schema.csv | csvformat -D ";"

가지다

Code;Task;ID;PROP;X;Remarks
AAA;P00_1;000;Lean;-;not yet done
AAB;P00_2;11;Fat;X;20190606
AAC;P00_3;1;Midle;X;canceled

답변2

GNU awk의 경우 FIELDWIDTHS다음을 사용합니다.고정 너비 데이터 처리. 테이블 개요에서 필드 너비를 가져옵니다. 각 필드의 후행 공백을 제거합니다.

BEGIN { FS = "+"; OFS = ";" }
NR == 2 { 
  for (i=1;i<=NF;i++) f = (f ? f " " : "") length($i)+1
  FIELDWIDTHS = f
  print "Code;Task#;ID;PROP;X;Remarks"
}
!/^;/ {
  for (i=1;i<=NF;i++) sub(/[[:space:]]+$/,"",$i)
  print
}

용법:

$ awk -f tst.awk file
Code;Task#;ID;PROP;X;Remarks
AAA;P00_1;000;Lean;-;not yet done
AAB;P00_2;11;Fat;X;20190606
AAC;P00_3;1;Midle;X;canceled

답변3

awk '
NR == 2 {
        for (i = 1; i <= length(); i++) {
                if (substr($0, i, 1) == "+" || i == length()) {
                        fieldWidths[++fieldNr] = i - prevFieldEndPos
                        prevFieldEndPos = i
                }
        }
}

NR > 5 {
        fieldNr = 0
        for (i = 1; i <= length(); i += fieldWidths[fieldNr]) {
                fieldVal = substr($0, i, fieldWidths[++fieldNr])
                gsub(/^[[:blank:]]*|[[:blank:]]*$/, "", fieldVal)
                printf "%s", (i > 1 ? ";" : "") fieldVal
        }
        print ""
}' infile

출력(입력 방법이 명확하지 않아 헤더 부분을 처리하지 않음):

AAA;P00_1;000;Lean;-;not yet done
AAB;P00_2;11;Fat;X;20190606
AAC;P00_3;1;Midle;X;canceled

관련 정보