awk vs Scala
Dans la série “the right tool for the right job”, j’ai besoin d’un petit programme qui filtre
certaines lignes d’un fichier, au format csv. Je veux filtrer les enregistrements pour lesquelles le
nombre de lignes contenant la première colonne est inférieur à un seuil, l’équivalent d’un
HAVING(COUNT(*)) > seuil
en SQL.
Prenons un exemple pour clarifier cela : un fichier pays.csv contenant des couples pays, ville
France,Paris
France,Grenoble
France,Marseille
Espagne,Barcelone
Espagne,Madrid
Le but est de supprimer tous les pays ayant moins de 3 villes.
France,Paris
France,Grenoble
France,Marseille
J’ai voulu tester 2 approches différentes : une première en ligne de commandes et une deuxième avec Scala.
awk
La boite à outils Unix permettant de rendre des services inestimables, j’ai implémenté une version avec awk :
awk 'BEGIN { FS=","; OFS=","} {id[$0]=$1; lines[$0]=$0; count[$1]++;} END { for (line in lines) if(count[id[line]] > 2) print line}' pays.csv
Scala
import scala.io.Source._
import java.io.PrintWriter
object awk extends App {
val out = new PrintWriter("/home/yamo/pays.res")
fromFile("/home/yamo/pays.csv")
.getLines()
.toList
.groupBy(_.split(",")(0))
.filter(_._2.length > 2)
.flatMap(_._2)
.foreach(out.println(_))
out.close
}
Conclusion
Étant débutant dans ces 2 langages, je pense que les solutions ne sont pas optimales. D’ailleurs, n’hésitez pas à me proposer vos améliorations. L’implémentation AWK est plus concise, et utilise un tableau mutable. Le code Scala est plus verbeux mais orienté fonctionnel et plus lisible.