1

Say I have an array of some elements, and I want to save the data related to each element in a CSV file. This is my code:

require 'rubygems'
require 'csv'

category_ID = [-1, 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 15, 17, 18, 19, 20, 21, 91, 92, 93, 94, 101, 102, 103, 104, 105, 106, 107, 111, 112, 113, 114, 115, 116, 117, 118, 119]

CSV.foreach('C:\Users\username\Desktop\Original.csv', :headers=>true) do |row,i|
    category_ID.each {|x|}
        CSV.open('C:\Users\username\Desktop\#{x}.csv', "wb") do |csv|           
            if row[4].gsub(/^[^:]+:\s*/,"") == x
                csv << row[28].gsub(/^[^:]+:\s*/,"")
            end
        end
    end
end

So I want my file names to be -1.csv, 0.csv, 1.csv, ... , 119.csv. But it is giving an error because of the #{x} as the file name. How to correct this? Thanks.

EDIT: This is 1 row from the Original.csv file:

"{""timestamp"""," ""2015-05-10 15",59,"59"""," ""article_category_id"""," ""106"""," ""app_name"""," ""Apple Daily TW"""," ""ip"""," ""111.80.37.218"""," ""app_id"""," ""51ee0d904055aa1539d32523"""," ""datetime"""," ""1431273612198"""," ""edition"""," """""," ""action"""," ""page_view"""," ""article_title"""," ""【溫星母親節】潘若迪竟讓老婆一個人過"""," ""user_id"""," """""," ""menu"""," ""即時新聞"""," ""lon"""," """""," ""platform"""," ""Android"""," ""country_residence"""," """""," ""version"""," ""2.5.2"""," ""page_name"""," ""【溫星母親節】潘若迪竟讓老婆一個人過"""," ""location"""," """""," ""is_registered"""," ""False"""," ""provider"""," """""," ""page_id"""," ""607814"""," ""menu_id"""," ""10002""","  ""article_category"""," ""娛樂"""," ""lat"""," """""," ""article_id"""," ""607814"""," ""country_origin"""," """""," ""udid"""," ""d0155049772de9"""," ""gender"""," """""," ""age"""," """""," ""device"""," ""C6902"""," ""session_id"""," """""," ""push"""," ""N"""," ""os"""," ""4.4.2"""," ""browser"""," """"}",,
8
  • shouldn't that be c:\users\username\desktop ? where username is your .. username Commented Dec 23, 2016 at 11:52
  • Yeah, true. I modified the actual path, and in doing so I forgot about the username part. Commented Dec 23, 2016 at 11:56
  • always use interpolation in double quotes Commented Dec 23, 2016 at 12:01
  • @ShaileshPrajapati Ok, got it. But even after fixing it, its not producing any output file. Commented Dec 23, 2016 at 12:02
  • Could you please show a few lines of your original CSV file? Your code is a bit confusing. Commented Dec 23, 2016 at 12:13

3 Answers 3

5

This line is a noop:

category_ID.each {|x|}

I guess you wanted to:

category_ID.each do |x|
  CSV.open("C:\Users\Desktop\#{x}.csv", "wb") do |csv|
    if row[4].gsub(/^[^:]+:\s*/,"") == x
      csv << row[28].gsub(/^[^:]+:\s*/,"")
    end
  end
end
Sign up to request clarification or add additional context in comments.

5 Comments

I see. But even with this code, it is giving the following error: Invalid argument @ rb_sysopen - C:\Users\Desktop\|x|.csv (Errno::EINVAL).
Ah, interpolated string should be in double quotes, please see an update.
Ah, I see. I didn't know that! Thanks for sharing this knowledge. Confusing and quirky little language, Ruby. But now even though the code runs without error, it does not produce any output file. Why could that be?
Does `C:\Users\Desktop` really exist, or isn't the user name missing?
@EricDuminil Yeah, fixed it.
2

Change following line

CSV.open('C:\Users\Desktop\#{x}.csv', "wb") do |csv|  

to

CSV.open("C:\Users\Desktop\#{x}.csv", "wb") do |csv|  

UPDATE

require 'rubygems'
require 'csv'

category_ID = [-1, 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 15, 17, 18, 19, 20, 21, 91, 92, 93, 94, 101, 102, 103, 104, 105, 106, 107, 111, 112, 113, 114, 115, 116, 117, 118, 119]

CSV.foreach('C:\Users\username\Desktop\Original.csv', :headers=>true) do |row,i|
    category_ID.each do |x|
        CSV.open("C:\Users\username\Desktop\#{x}.csv", "wb") do |csv|           
            if row[4].gsub(/^[^:]+:\s*/,"") == x
                csv << row[28].gsub(/^[^:]+:\s*/,"")
            end
        end
    end
end

5 Comments

Ok, the code now runs without error, but it does not produce any output file.
@Kristada673 try this CSV.open("C:\Users\Desktop\#{x}.csv", "a+")
No, it wouldn't work either, because the file is not even being created. Not even a blank file.
@Kristada673. please see update and try.you forget to write do after .each.remove curly braces.
Yeah, I saw the small error there, I tried it in the proper way itself. :) No file produced.
1

For the interpolation problem in single quotes, see the answers of mudasobwa and Santosh.

I presume you still get no output because the weird CSV you use. To test this open one of the CSV in the simplest way there is, so no other issues can interfere. I added options to handle malformed CSV. You should see only your data files, nothing else, otherwise filter out the other stuff. Once you are sure your original CSV is read correctly, then try the writing part.

NB the CSV.foreach doesn't provide an index.

CSV.foreach('C:\Users\username\Desktop\Original.csv', :headers=>true, force_quotes: false, :quote_char => "\x00") do |row|
  p row
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.