Devo essere in grado di capire quale delimitatore viene utilizzato in un file CSV (virgola, spazio o punto e virgola) nel mio progetto Ruby. Lo so, esiste una classe Sniffer in Python nel modulo csv che può essere utilizzata per indovinare il delimitatore di un determinato file. C'è qualcosa di simile a questo in Ruby? Ogni tipo di aiuto o idea è molto apprezzato.Ruby: come posso rilevare/indovinare in modo intelligente il delimitatore utilizzato in un file CSV?
Ruby: come posso rilevare/indovinare in modo intelligente il delimitatore utilizzato in un file CSV?
risposta
Sembra che l'implementazione py controlli solo alcuni dialetti: excel o excel_tab. Quindi, una semplice implementazione di qualcosa che solo controlla per ","
o "\t"
è:
COMMON_DELIMITERS = ['","',"\"\t\""]
def sniff(path)
first_line = File.open(path).first
return nil unless first_line
snif = {}
COMMON_DELIMITERS.each {|delim|snif[delim]=first_line.count(delim)}
snif = snif.sort {|a,b| b[1]<=>a[1]}
snif.size > 0 ? snif[0][0] : nil
end
Nota: che sarebbe restituire l'intero delimitatore che trova, ad esempio, ","
, quindi per ottenere ,
è possibile modificare snif[0][0]
in snif[0][0][1]
.
Inoltre, sto usando count(delim)
perché è un po 'più veloce, ma se hai aggiunto un delimitatore composto da due (o più) caratteri dello stesso tipo come --
, allora potrebbe ogni occorrenza due volte (o più) quando si pesa il tipo, quindi in tal caso, potrebbe essere meglio usare scan(delim).length
.
Non sono a conoscenza di alcuna implementazione dello sniffer nella libreria CSV inclusa in Ruby 1.9. Proverà a scoprire automaticamente il separatore di riga, ma si presume che il separatore di colonne sia una virgola per impostazione predefinita.
Un'idea sarebbe provare a analizzare un numero di esempio di righe (il 5% del totale forse?) Utilizzando ciascuno dei possibili separatori. Indipendentemente dal separatore, lo stesso numero di colonne è il separatore corretto.
Ecco la risposta Gary S. Weaver mentre la stiamo usando in produzione. Buona soluzione che funziona bene.
class ColSepSniffer
NoColumnSeparatorFound = Class.new(StandardError)
EmptyFile = Class.new(StandardError)
COMMON_DELIMITERS = [
'","',
'"|"',
'";"'
].freeze
def initialize(path)
@path = path
end
def self.find(path)
new(path: path).find
end
def find
fail EmptyFile unless first
if valid?
delimiters[0][0][1]
else
fail NoColumnSeparatorFound
end
end
private
def valid?
!delimiters.collect(&:last).reduce(:+).zero?
end
# delimiters #=> [["\"|\"", 54], ["\",\"", 0], ["\";\"", 0]]
# delimiters[0] #=> ["\";\"", 54]
# delimiters[0][0] #=> "\",\""
# delimiters[0][0][1] #=> ";"
def delimiters
@delimiters ||= COMMON_DELIMITERS.inject({}, &count).sort(&most_found)
end
def most_found
->(a, b) { b[1] <=> a[1] }
end
def count
->(hash, delimiter) { hash[delimiter] = first.count(delimiter); hash }
end
def first
@first ||= file.first
end
def file
@file ||= File.open(@path)
end
end
Spec
require "spec_helper"
describe ColSepSniffer do
describe ".find" do
subject(:find) { described_class.find(path) }
let(:path) { "./spec/fixtures/google/products.csv" }
context "when , delimiter" do
it "returns separator" do
expect(find).to eq(',')
end
end
context "when ; delimiter" do
let(:path) { "./spec/fixtures/google/products_with_semi_colon_seperator.csv" }
it "returns separator" do
expect(find).to eq(';')
end
end
context "when | delimiter" do
let(:path) { "./spec/fixtures/google/products_with_bar_seperator.csv" }
it "returns separator" do
expect(find).to eq('|')
end
end
context "when empty file" do
it "raises error" do
expect(File).to receive(:open) { [] }
expect { find }.to raise_error(described_class::EmptyFile)
end
end
context "when no column separator is found" do
it "raises error" do
expect(File).to receive(:open) { [''] }
expect { find }.to raise_error(described_class::NoColumnSeparatorFound)
end
end
end
end
- 1. Posso importare un file CSV e inferire automaticamente il delimitatore?
- 2. esplode file csv su delimitatore (;) e delimitatore (,)?
- 3. file CSV di lettura in cui NumPy delimitatore è ""
- 4. Ruby: come posso leggere un file CSV che contiene due intestazioni in Ruby?
- 5. Modifica del separatore di campo/delimitatore nel file CSV esportato utilizzando Ruby CSV
- 6. Come importare un file CSV con delimitatore come ";" e separatore decimale come "," in SAS?
- 7. Come posso leggere CSV senza quote_char in ruby?
- 8. Come posso dividere un file CSV in PHP?
- 9. Come posso rilevare i campi mancanti in un file CSV in modo Pythonic?
- 10. C - Determinare quali delimitatore utilizzato - strtok()
- 11. È un modo intelligente per organizzare il codice in jQuery?
- 12. Tavole reattive, il modo intelligente
- 13. Converti .json in .csv in ruby
- 14. Utilizzo della classe CSV per analizzare un file .csv in Ruby
- 15. Come ottenere un file .csv in R?
- 16. Come leggere il file CSV in Android?
- 17. Come posso "estrapolare" i valori da una matrice multidimensionale in modo intelligente?
- 18. Come risolvere in modo intelligente la documentazione in Eclipse?
- 19. Come posso cancellare in modo sicuro un file?
- 20. Come dovrei rilevare quale delimitatore è usato in un file di testo?
- 21. Come utilizzare SQL in un file CSV
- 22. Come scrivere ArrayList in un file csv
- 23. come convertire un file XML in file CSV in javascript
- 24. come ordinare il file in ruby
- 25. Come posso saltare la riga di intestazione durante la lettura di un CSV in Ruby? Classe
- 26. Il modo più efficiente di convertire un DataTable in CSV
- 27. Scrivere in un file CSV in Node.js
- 28. C'è un modo semplice per convertire il file .xls in un file .csv? (Excel)
- 29. Come cambio il dtype in TensorFlow per un file csv?
- 30. Come posso importare un file CSV tramite un'attività rake?
Tecnicamente, solo uno di questi è un file CSV ... –