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
위의 예제 데이터에서는 일부 행이 두 개의 행으로 분할되었습니다. 그것을 청소하는 방법?
고쳐 쓰다
- csv 파일은 Microsoft 플랫폼에서 생성됩니다. 그래서 줄은 .으로 끝납니다
^m
. 저는 Linux에서 샘플 데이터를 썼습니다\n
. 명확하게 하지 않은 것은 제 잘못입니다. 그러나 나는 그것을 대신\n
사용할\r\n
. - 개행 문자는 항상 쉼표 앞에 나타나는 것은 아니며, 이와 같은 필드에서도 무작위로 나타납니다.
.
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
여기서는 분할 앞에 항상 쉼표가 붙는다고 가정합니다 ,
.