0

そのため、文字列形式の金額を含む 2 つの列を持つ CSV があります。head -n 5 file.csv次のことを明らかにします。

Title,Distributor Long Name,Wk,Estimated Weekend Gross,Cume,Locs Reported,Avg/Loc,Booking Title #
"=""Zero Dark Thirty""","=""Sony""",4,"24,000,000","29,480,807",2937,"8,172","=""66273"""
"=""Haunted House, A""","=""Open Road""",1,"18,817,000","18,817,000",2160,"8,712","=""71209"""
"=""Gangster Squad""","=""Warner Bros.""",1,"16,710,000","16,710,000",3103,"5,385","=""66556"""
"=""Django Unchained""","=""The Weinstein Company""",3,"11,065,000","125,399,122",3012,"3,674","=""66122"""

これが約40行続きます。"Estimated Weekend Gross" と "Cume" の 2 つの列の値が string になっていることに気付くでしょ

私の質問は、これらの 2 つの列のみを反復処理し、文字列値を整数に変換して、同じCSVrow.to_s.gsub(',','').to_iのそれぞれの行にそれらの値を上書きする方法はありますか?

私はこのようなことをしようとしましたが、適切にフォーマットされたCSVを取得していません..

File.open('modified.csv', 'w') do |csv|
  CSV.foreach('original.csv') do |row|
    csv << row[0].to_s.gsub('=','').gsub(', The','')
    csv << row[3].to_s.gsub(',','').to_i
    csv << row[4].to_s.gsub(',','').to_i
  end
end

ブロックを実行するときにも遊んでみまし:headers => :integerたが、値を文字列から整数に変換することはできません。それで、私は何が欠けていますか?これらの値を保存してから新しい CSV を作成する必要がありますか、それとももっと簡単な方法がありますか?

4

3 に答える 3

3

アーロン、行を変更して、次のように新しいファイルに書き込んでください

require 'csv'

File.open('modified.csv', 'w') do |csv|
  CSV.foreach('original.csv', :headers => true) do |row|
    row['Estimated Weekend Gross'] = row['Estimated Weekend Gross'].delete(',').to_i
    row['Cume'] = row['Cume'].delete(',').to_i
    csv << row
  end
end

編集: ヘッダーを modified.csv に保存したい場合は、このようにすることができますが、誰かがこれに対するより良い解決策を持っている場合、ファイルを 2 回開かずに短い方法が必要です。

headers = CSV.open('original.csv', 'r', :headers => true).read.headers
CSV.open('modified.csv', 'w') do |csv|
  csv << headers
  CSV.foreach('original.csv', :headers => true) do |row|
    row['Estimated Weekend Gross'] = row['Estimated Weekend Gross'].delete(',').to_i
    row['Cume'] = row['Cume'].delete(',').to_i
    csv << row
  end
end
于 2013-01-14T10:23:28.203 に答える
0

これを試すことができますか:

CSV.open('modified.csv', 'w') do |csv|
  CSV.foreach('original.csv') do |row|
    modified_row = row.clone
    modified_row[0] = row[0].to_s.gsub('=','').gsub(', The','')
    modified_row[3] = row[3].to_s.gsub(',','').to_i
    modified_row[4] = row[4].to_s.gsub(',','').to_i
    csv << modified_row
  end
end

書き込み用のファイル オープンを CSV を使用するように変更し、個別の値を追加するのではなく、行行の配列を追加するように追加を修正しました。

于 2013-01-14T10:13:31.307 に答える
0

これを使用して取得できます:

sed 's/,\("[^"]*"\)*/|\1/g' file.csv | awk -F"|" '{s="";for (i=1; i<=NF; i++){if (i==4 || i==5){gsub("\,","",$i);gsub("\"","",$i);s=s","$i;}else{if (i>1){s=s","$i;}else{s=s""$i;}}}print s;}' -

私はこの出力を得ました:

"=""Zero Dark Thirty""","",4,24000000,29480807,2937,"8,172",""
"=""Haunted House, A""","",1,18817000,"18,817,000",2160,"8,712",""
"=""Gangster Squad""","",1,16710000,16710000,3103,"5,385",""
"=""Django Unchained""","",3,11065000,125399122,3012,"3,674",""

わかりにくいと思いますので、順を追って説明します。

  1. まず、引用符を考慮して、各フィールドに区切り記号を作成します。

    sed 's/,("[^"] ") /|\1/g' file.csv

そして、パイプセパレーター「|」が得られます 各フィールド間:

"=""Zero Dark Thirty"""|""|4|"24,000,000"|"29,480,807"|2937|"8,172"|""
"=""Haunted House| A"""|""|1|"18,817,000"|"18,817,000"|2160|"8,712"|""
"=""Gangster Squad"""|""|1|"16,710,000"|"16,710,000"|3103|"5,385"|""
"=""Django Unchained"""|""|3|"11,065,000"|"125,399,122"|3012|"3,674"|""
  1. パイプをフィールドセパレーターとして使用してこの出力を取得したら、awk を使用して、説明したフィルターをフィールド 4 と 5 に適用できます (sed の出力を入力として受け取るため、sed コマンドの後に実行する必要があります)。

    awk -F"|" '{s="";for (i=1; i<=NF; i++){if (i==4 || i==5){gsub("\,","",$i);gsub ("\"","",$i);s=s","$i;}else{if (i>1){s=s","$i;}else{s=s""$私;}}}プリント;}' -

各フィールドの引用符とコンマを (整数表現として) 削除し、目的の出力を取得します。

"=""Zero Dark Thirty""","",4,24000000,29480807,2937,"8,172",""
"=""Haunted House, A""","",1,18817000,"18,817,000",2160,"8,712",""
"=""Gangster Squad""","",1,16710000,16710000,3103,"5,385",""
"=""Django Unchained""","",3,11065000,125399122,3012,"3,674",""
于 2013-01-14T09:32:49.150 に答える