CSV 파일의 열에서 줄 바꿈 제거

CSV 파일의 열에서 줄 바꿈 제거

CSV 파일의 열에 개행 문자가 표시됩니다. 이 열의 데이터는 연속된 행에 있습니다. 예를 들어:

ID,CODE,MESSAGE,DATE,TYPE,OPER,CO_ID
12202,INT_SYS_OCS_EX_INT-0000,"""OCSSystemException: HTTP transport error: java.net.ConnectException: Tried all: '1' addresses, but could not connect over HTTP to server: '10.244.166.9', port: '8080'
 failed reasons:
  [0] address:'/10.244.166.9',port:'8080' : java.net.ConctException: Connection refused
""",06-09-2021 05:52:32,error,BillCycle,6eb8642aa4b
20840,,,06-09-2021 16:17:18,response,changeLimit,1010f9ea05ff

문제는 열과 MessageID 12202에 있습니다. 여기서 데이터는 삼중따옴표와 연속 행에 있습니다.

내 요구 사항은 columns 에 대해 Message데이터가 여러 행이 아닌 단일 행에 표시되어야 한다는 것입니다. 내 etl 로더는 포함된 개행 문자를 가져올 수 없기 때문입니다.

답변1

CSV가 Excel과 같은 MS 도구로 생성된 경우 아래와 같이 필드 중앙의 "줄 바꿈 문자"는 LF이고 각 레코드 끝에 있는 "줄 바꿈 문자"는 CRLF입니다(" 필드 끝$ 의 LF에 줄바꿈"을 입력 하고 레코드 CRLF를 입력합니다.^M$

$ cat -Ev file
ID,Code,Message,date^M$
1244,,"""Exception error : java connection error$
:8080 Connection refused""",01-09-2021^M$

그렇다면 레코드가 CRLF로 끝나고 중간 레코드 LF를 공백으로 바꾸도록 GNU awk(다중 문자 RS의 경우)에 알릴 수 있습니다.

$ awk -v RS='\r\n' '{gsub(/\n/," ")} 1' file
ID,Code,Message,date
1244,,"""Exception error : java connection error :8080 Connection refused""",01-09-2021

POSIX awk만 있고 CSV용 도구가 없는 경우 다음을 참조하세요.awk를 사용하여 CSV를 효율적으로 구문 분석하는 가장 강력한 방법은 무엇입니까이를 어떻게 해야 하는지 알아보거나 CR이 파일의 다른 곳에 나타나지 않는 경우 awk를 사용하여 이를 수행할 수 있습니다.

$ awk -v RS='\r' 'NR>1{print prev} {sub(/^\n/,""); gsub(/\n/," "); prev=$0}' file
ID,Code,Message,date
1244,,"""Exception error : java connection error :8080 Connection refused""",01-09-2021

답변2

간단한 방법은 필드가 3개만 있는 줄에서 개행 문자를 제거하는 것입니다.

$ perl -F','  -pane 's/\n// if $#F==2' file 
ID,Code,Message,date
1244,,"""Exception error : java connection error:8080 Connection refused""",01-09-2021
1245,,"""Exception error :""",01-09-2021
1246,,"ffadsdasd",01-09-2021

물론 이는 ,CSV 파일에서 허용되는 내부 필드를 가질 수 없다고 가정합니다. 따라서 Message필드에 이와 같은 내용이 포함되어 있으면 """foo,bar"""실패할 수 있습니다. 그렇기 때문에 항상 전용 파서를 사용하는 것이 더 좋습니다.

이 방법은 유효한 CSV 파일에서 작동합니다.

$ perl -MText::CSV -le '$csv = Text::CSV->new({binary=>1}); while ($row = $csv->getline(STDIN)){ $row->[2]=~s/\n//; $csv->print(STDOUT,$row)}' < file
ID,Code,Message,date
1244,,"""Exception error : java connection error:8080 Connection refused""",01-09-2021
1245,,"""Exception error :""",01-09-2021
1246,,ffadsdasd,01-09-2021

답변3

csvkit유틸리티가 있는 경우 , 예를 들어 줄바꿈을 리터럴 두 문자로 변환하여 줄바꿈이 포함된 행을 수정할 수 있습니다 \n.

csvformat -M $'\r' datafile |                    # temporarily end lines with $'\r'
    sed -e ':a' -e 'N;$!ba' -e 's/\n/\\n/g' |    # transform $'\n' into '\n'
    tr '\r' '\n'                                 # convert the line endings back to $'\n'

csvkit github의 포스터 덕분에그들의 솔루션, 이는 다음으로 다시 연결됩니다.답변스택오버플로우에서

답변4

첫 번째 단계는 CSV 파일을 실행하고 Unix 줄 끝으로 변환하는 것입니다.

dos2unix your_csvfile

\r\n다음 단계에서는 "then" 으로 변경됩니다 .\n

GNU sed를 사용하여 다음과 같이 짝수/홀수 큰따옴표를 추적합니다.

sed -Ee '
  h;s/[^"]*//g
  /^(..)*$/!{
    z;G;N;D
  }
  g;s/\n//g
' your_csvfile

perl -pe 's/\n/<>/e while y/"// % 2' your_csvfile

awk 유틸리티를 사용하여 큰따옴표의 수를 세고 짝수가 될 때까지 줄을 계속 누적할 수 있습니다.

awk '{
  t = $0
  while ((gsub(/"/,"&",t) ~ /[13579]$/) && (getline nxt > 0)) 
    t = t nxt
  print t
}' your_csvfile

산출:

     1  ID,Code,Message,date$
     2  1244,,"""Exception error : java connection error:8080 Connection refused""",01-09-2021$

관련 정보