CSV 파일 열에서 개행 문자를 감지하고 제거하는 방법은 무엇입니까?

CSV 파일 열에서 개행 문자를 감지하고 제거하는 방법은 무엇입니까?

csv데이터베이스에서 내보낸 대용량 파일(200만 행)이 있습니다 SQL Server. 데이터베이스에 액세스할 수 없으며 R.

샘플 데이터는 다음과 같습니다.

playerID,yearID,gameNum,gameID,teamID,lgID,GP,startingPos
gomezle01,1933,0,ALS193307060,NYA,AL,1,1
ferreri01,1933,0,ALS193307060,BOS,AL,1,2
gehrilo01,1933,0
,ALS193307060,NYA,AL,1,3
gehrich01,1933,0,ALS193307060,DET,AL,1,4
dykesji01,1933,0,ALS193307060,CHA,AL,1,5
cronijo01,1933,0,ALS193307060
,WS1,AL,1,6
chapmbe01,1933,0,ALS193307060,NYA,AL,1,7
simmoal01,1933,0,ALS193307060,CHA,AL,1,8
ruthba01,1933,0,ALS193307060,NYA,AL,1,9

위의 예제 데이터에서는 일부 행이 두 개의 행으로 분할되었습니다. 그것을 청소하는 방법?

고쳐 쓰다

  1. csv 파일은 Microsoft 플랫폼에서 생성됩니다. 그래서 줄은 .으로 끝납니다 ^m. 저는 Linux에서 샘플 데이터를 썼습니다 \n. 명확하게 하지 않은 것은 제 잘못입니다. 그러나 나는 그것을 대신 \n사용할 \r\n.
  2. 개행 문자는 항상 쉼표 앞에 나타나는 것은 아니며, 이와 같은 필드에서도 무작위로 나타납니다.

.

Bill 
Gates.

해결됨

1단계: ^M줄 중앙에서 제거합니다.

perl -pe 's/\r(?!\n)//g'

인용하다:https://stackoverflow.com/questions/6081465/how-to-remove-carriage-returns-in-the-middle-of-a-line

2단계: \n,다음으로 교체 ,(아래 @jimmij의 답변 참조)

perl -p00e 's/\n,/,/g' 

답변1

우리는 이것을 테스트 파일로 사용합니다:

$ cat file
playerID,yearID,gameNum,gameID,teamID,lgID,GP,startingPos
gomezle01,1933,0,ALS193307060,NYA,AL,1,1
ferreri01,1933,0,ALS193307060,BOS,AL,1,2
gehrilo01,1933,0
,ALS193307060,NYA,AL,1,3
gehrich01,1933,0,ALS193307060,DET,AL,1,4
dykesji01,1933,0,ALS193307060,CHA,AL,1,5
cronijo01,1933,0,ALS193307060
,WS1,AL,1,6
chapmbe01,1933,0,ALS193307060,NYA,AL,1,7
simmoal01,1933,0,ALS193307060,CHA,AL,1,8
ruthba01,1933,0,ALS193307060,NYA,AL,1,9
Bill
Gates,1933,0,ALS193307060,NYA,AL,1,9

그러면 행이 다시 합쳐집니다.

$ awk 'NR==1{printf "%s",$0; gsub(/[^,]/,""); nlast=n=length($0); next;} nlast==n{printf "\n";nlast=0} {printf "%s",$0; gsub(/[^,]/,""); nlast+=length($0)} END{print ""}' file
playerID,yearID,gameNum,gameID,teamID,lgID,GP,startingPos
gomezle01,1933,0,ALS193307060,NYA,AL,1,1
ferreri01,1933,0,ALS193307060,BOS,AL,1,2
gehrilo01,1933,0,ALS193307060,NYA,AL,1,3
gehrich01,1933,0,ALS193307060,DET,AL,1,4
dykesji01,1933,0,ALS193307060,CHA,AL,1,5
cronijo01,1933,0,ALS193307060,WS1,AL,1,6
chapmbe01,1933,0,ALS193307060,NYA,AL,1,7
simmoal01,1933,0,ALS193307060,CHA,AL,1,8
ruthba01,1933,0,ALS193307060,NYA,AL,1,9
BillGates,1933,0,ALS193307060,NYA,AL,1,9

줄 끝 요구 사항이 명확하지 않습니다. 여기에 코드를 추가하여 처리할 수 있습니다. 또는 유연성을 최대화하기 위해 필요에 따라 dos2unix파일 을 실행할 수 있습니다 unix2dos.

질문의 첫 번째 버전에 대한 답변

큰(200만 행) csv 파일이 있습니다.

다음은 전체 파일을 한 번에 메모리로 읽을 필요가 없는 라인 기반 솔루션입니다.

$ awk 'NR>1 && !/^,/{printf "\n";} {printf "%s",$0} END{print ""}' file
playerID,yearID,gameNum,gameID,teamID,lgID,GP,startingPos
gomezle01,1933,0,ALS193307060,NYA,AL,1,1
ferreri01,1933,0,ALS193307060,BOS,AL,1,2
gehrilo01,1933,0,ALS193307060,NYA,AL,1,3
gehrich01,1933,0,ALS193307060,DET,AL,1,4
dykesji01,1933,0,ALS193307060,CHA,AL,1,5
cronijo01,1933,0,ALS193307060,WS1,AL,1,6
chapmbe01,1933,0,ALS193307060,NYA,AL,1,7
simmoal01,1933,0,ALS193307060,CHA,AL,1,8
ruthba01,1933,0,ALS193307060,NYA,AL,1,9

어떻게 작동하나요?

  • NR>1 && !/^,/{printf "\n";}

    첫 번째 줄에 있지 않고 NR>1현재 줄이 쉼표로 시작하지 않으면 !/^,/개행 문자가 인쇄됩니다.

  • {printf "%s",$0}

    개행 없이 현재 줄을 인쇄합니다.

  • END{print ""}

    파일 끝에 도달하면 마지막 줄을 끝내기 위해 또 다른 개행 문자가 인쇄됩니다.

답변2

perl구조하다:

$ perl -p00e 's/\n,/,/g' file
playerID,yearID,gameNum,gameID,teamID,lgID,GP,startingPos
gomezle01,1933,0,ALS193307060,NYA,AL,1,1
ferreri01,1933,0,ALS193307060,BOS,AL,1,2
gehrilo01,1933,0,ALS193307060,NYA,AL,1,3
gehrich01,1933,0,ALS193307060,DET,AL,1,4
dykesji01,1933,0,ALS193307060,CHA,AL,1,5
cronijo01,1933,0,ALS193307060,WS1,AL,1,6
chapmbe01,1933,0,ALS193307060,NYA,AL,1,7
simmoal01,1933,0,ALS193307060,CHA,AL,1,8
ruthba01,1933,0,ALS193307060,NYA,AL,1,9

여기서는 분할 앞에 항상 쉼표가 붙는다고 가정합니다 ,.

관련 정보