2

大きな(50GB)csvファイルを小さな部分に分割するのに苦労しています。各行には数千のフィールドがあります。一部のフィールドは二重引用符で囲まれた文字列であり、その他のフィールドは整数、小数、ブール値です。

ファイルを1行ずつ解析し、各行のフィールド数で分割したいと思います。文字列には、いくつかのコンマ(など)と、いくつかの空のフィールドが含まれている可能性があります。

,, 1,30,50、 "父、息子、娘が4,000ドルで販売" ,,,,, 12 ,,, 20.9,0、

使ってみました

perl -pe'  s{("[^"]+")}{($x=$1)=~tr/,/|/;$x}ge  '  file >> file2

引用符内のコンマを|に変更します しかし、それはうまくいきませんでした。使用する予定です

awk -F"|" conditional statement appending to new k_fld_files file2

これを行う簡単な方法はありますか?私はPythonを見ていますが、ファイルを1行ずつストリーム処理するユーティリティがおそらく必要です。

4

2 に答える 2

3

Pythonの使用-埋め込まれた区切り文字を含むCSVを解析し、新しい区切り文字でストリーミングしたい場合は、次のようになります。

import csv
import sys
with open('filename.csv') as fin:
    csvout = csv.writer(sys.stdout, delimiter='|')
    for row in csv.reader(fin):
        csvout.writerow(row)

そうでなければ、これにあらゆる種類のことをさせることはそれほど難しくありません。

列ごとにファイルに出力する例(テストされていない):

cols_to_output = {}
for row in csv.reader(fin):
    for colno, col in enumerate(row):
        output_to = cols_to_output.setdefault(colno, open('column_output.{}'.format(colno), 'wb')
        csv.writer(output_to).writerow(row)

for fileno in cols_to_output.itervalues():
    fileno.close()
于 2012-08-17T00:50:02.687 に答える
2

別の方法がありawkます。

引用符で囲まれた文字列が適切にフォーマットされている、つまり常に開始引用符と終了引用符があり、他の引用符内に引用符がない場合、gsub他のすべてのフィールドでを置き換え,て、提案した置換を行うことができます|

パイプ付き

以下は、3列目から6列目、11列目、および14-15列目を次のように取得した場合の例ですcoreutils cut

awk -F'"' -v OFS='' '
  NF > 1 { 
    for(i=2; i<=NF; i+=2) { 
      gsub(",", "|", $i);
      $i = FS $i FS;       # reinsert the quotes
    }
    print
  }'\
| cut -d , -f 3-6,11,14-15 \
| awk -F'"' -v OFS='' -e '
    NF > 1 { 
      for(i=2; i<=NF; i+=2) { 
        gsub("\\|", ",", $i)
        $i = FS $i FS;       # reinsert the quotes
      }
      print
    }'

に戻す追加の後処理ステップがあることに注意して|ください,

完全にawkで

awkあるいは、範囲の指定に関して一般性をいくらか失うことで、すべてを行うことができます。ここでは、列3から6のみを取得します。

extract.awk

BEGIN {
  OFS   = ""
  start = 3
  end   = 6
}
{
  for(i=2; i<=NF; i+=2) {
    gsub(",", "|", $i)
    $i = FS $i FS
  }
  split($0, record, ",")
  for(i=start; i<=end-1; i++) {
    gsub("\\|", ",", record[i])
    printf("%s,", record[i])
  }
  gsub("\\|", ",", record[end])
  printf("%s\n", record[end])
}
于 2012-08-17T11:55:45.700 に答える