2010-11-26 51 views
0

J'ai une colonne de chaînes (villes) dans un fichier csv. Je devrais parcourir la liste, parcourir tous les modèles correspondants, ne conserver que le premier et remplacer tous les modèles similaires par des lignes vides. Je ne suis pas programmeur, mais si je pouvais faire ça, cela m'aiderait beaucoup au travail! J'ai des notions de Ruby et des notions de regexp dans Emacs. Est-ce faisable? Quelqu'un peut-il aider?Ruby, itération à travers des chaînes, correspondant à des motifs précis et remplaçant chacun sauf le premier

Merci d'avance!

fichier ressemble à ce:

Bordeaux

Bordeaux

Paris

Paris

Paris

Riom

fichier devrait ressembler à ceci:

Bordeaux

(blanc)

Paris

(blanc)

(blanc)

Riom

+0

Est-ce que les noms seront toujours regroupés ou pourraient-ils être entremêlés? –

+0

En outre, vous dites que vous devez faire cela avec plusieurs colonnes d'un fichier CSV? Pouvez-vous montrer un exemple plus complet de l'entrée si vous avez affaire à plusieurs colonnes? –

Répondre

2

Garder les lignes vides:

file_in = File.open('test_villes_ruby.txt','r') 
file_out = File.open('test_villes_ruby_stripped.txt','w') 

memo = "" 
file_in.each do |city| 
    if city == memo then 
    file_out << "\n" 
    else 
    file_out << city 
    memo = city 
    end 
end 

file_in.close 
file_out.close 
+0

Merci. En fait, il garde toutes les autres lignes ... – Zazaza

+0

Oh mon ... Réécrire, en ajoutant le fichier de sortie. – steenslag

+0

Merci beaucoup. Je serais ravi de parcourir mes fichiers en un tournemain ... (1 500 lignes, environ 10 colonnes dans des fichiers différents). Je ne me sentirai plus comme un esclave solitaire! – Zazaza

1

Pour ces tâches simples, vous pouvez également passer votre script Ruby directement à l'interpréteur en utilisant le paramètre de ligne de commande -e. Si vous le combinez avec -n ou -p, votre script ruby ​​sera exécuté sur chaque ligne de l'entrée, à tour de rôle. La variable $_ contient alors le contenu de la ligne en cours de traitement.

Donc, si votre fichier d'entrée ressemble à ceci:

jablan-mbp:dev $ cat test1.txt 
foo 
foo 
foo 
bar 
bar 
foo 
bar 
bar 
bar 
bar 
foo 

Vous pouvez exécuter un script simple de cette façon:

jablan-mbp:dev $ ruby -n -e 'puts(@memo == $_ ? "" : @memo = $_)' < test1.txt 
foo 


bar 

foo 
bar 



foo 
0

Solution:

File.open('cities', 'r') do |f_in| 
    File.open('cities_uniq', 'w') do |f_out| 
    f_in.inject("") { |o, c| f_out.puts o == c ? "\n" : c ; c} 
    end 
end 

Entrée:

Bordeaux 
Bordeaux 
Paris 
Paris 
Paris 
Riom 
Riom 
Riom 
Frankfurt 
Wien 
Wien 

Sortie:

Bordeaux 

Paris 


Riom 


Frankfurt 
Wien 

Note: Il y a une ligne vide après la finale « Wien », mais je ne peux pas à afficher ici ...

0

Probablement la manière simpliest est juste d'utiliser un ensemble (ou SortedSet si les questions d'ordre)

cities = Set.new 

cities_in_csv.each do |city| 
    cities.add(city) 
end 

rien de plus. Les ensembles, par définition, ne contiennent pas d'éléments en double.

+0

OP a demandé que les éléments dupliqués soient remplacés par des retours à la ligne. –

+0

Merci pour cela. J'ai raté cette partie. C'est ce que j'ai pour répondre à une question tard dans la nuit. – Olives