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

上記のサンプルデータでは、一部の行が2つの行に分割されています。それをきれいにする方法?

修正する

  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 ""}

    ファイルの終わりに達すると、最後の行を終了するために別の改行文字が印刷されます。

おすすめ記事