J'ai créé un modèle de script ruby qui traite un énorme fichier (même 1 million de lignes) ligne par ligne

Je copie et j'utilise le modèle lorsque je crée un gros fichier.

mérite

Modèle de script

Le script suivant est un script de lecture de CSV

--Si vous voulez jouer avec un fichier texte, cliquez ici (https://github.com/setsumaru1992/portableScripts/blob/master/frequent_use_codes/ruby_file_handlers/read_and_write_file.rb) --Si vous souhaitez effectuer un traitement d'agrégation après avoir vu toutes les lignes au lieu d'un traitement séquentiel de chaque ligne, [ici](https://github.com/setsumaru1992/portableScripts/blob/master/frequent_use_codes/ruby_file_handlers/read_csv_lines_and_write_result. rb)

require "csv"

$is_debug = true

def main(csv) #, output_file)
  # output_file_writer = CSV.open(output_file, "w")
  # output_cols = ["hoge"]
  # output_file_writer.puts(output_cols)

  FileHandler.csv_foreach(csv) do |row|
    #En traitement
    p row

    # output_row_values = []
    # output_file_writer.puts(output_row_values)
  end

  # puts "#{output_file}est créé"
  # output_file_writer.close
end

module FileHandler
  class << self
    def csv_foreach(csv)
      log "#{Time.now}: read start #{csv}"
      all_line_count = line_count(csv)

      return_values = CSV.foreach(csv, headers: true).with_index(1).map do |row, row_no|
        log progress(row_no, all_line_count) if progress_timing?(all_line_count, row_no)
        yield(row)
      end

      log "#{Time.now}: read end #{csv}"

      return_values
    end

    def line_count(file)
      open(file){|f|
        while f.gets; end
        f.lineno
      }
    end

    private

    def log(message)
      puts(message) if $is_debug
    end

    def progress_timing?(all_line_count, line_no)
      return false if all_line_count < 100

      #REMARQUE Changement en fonction du temps de traitement
      div_number = 100

      percent_unit = all_line_count / div_number
      line_no % percent_unit == 0
    end

    def progress(current_count, all_count)
      "#{Time.now}: #{CommonUtilities.percent(current_count, all_count)}% (#{CommonUtilities.number_with_commma(current_count)} / #{CommonUtilities.number_with_commma(all_count)})"
    end
  end
end

module CommonUtilities
  class << self
    def percent(num, all_count)
      (num.fdiv(all_count) * 100).round(2)
    end

    def number_with_commma(number)
      number.to_s.gsub(/(\d)(?=\d{3}+$)/, '\\1,')
    end
  end
end

main(ARGV[0])

Recommended Posts

J'ai créé un modèle de script ruby qui traite un énorme fichier (même 1 million de lignes) ligne par ligne
Je veux créer un fichier Parquet même en Ruby
[Ruby] J'ai créé un simple client Ping
J'ai fait une mort risquée avec Ruby
J'ai créé une application de visualisation qui affiche le PDF
J'ai créé une bibliothèque d'extension Ruby en C
J'ai créé un robot LINE avec Rails + heroku
J'ai fait un portfolio avec Ruby On Rails