web-dev-qa-db-fra.com

Comment rejoindre deux fichiers CSV?

Supposons que vous ayez un fichier CSV avec 2 champs: ID et email. Vous avez un autre fichier avec 2 champs: email et nom. Comment produire un fichier avec les trois champs associés sur le courrier électronique?

23
crst53

révision:

Vous devez trier les deux listes sur le courrier électronique alphabétiquement, puis rejoindre. Étant donné que le champ email est le 2e champ de fichier1 et le 1er champ de fichier2:

sort -t , -k 2,2 file1.csv > sort1.csv
sort -t , -k 1,1 file2.csv > sort2.csv
join -t , -1 2 -2 1 sort1.csv sort2.csv > sort3.csv

paramètre signification

 - T,: ',' est le séparateur de champ 
 - K 2,2: Trier des caractères sur le 2e champ [.____] - K 1,1: Triez le caractère sur le 1er champ 
 - 1 2: fichier 1, 2e champ [.____] - 2 1: fichier 2, 1er champ [.____]>: sortie vers le fichier [.____]

produit

 Email, ID, nom 
 Email, ID, nom 
 ... [.____]

trié par email alphabétiquement.

Notez que si un courrier électronique est manquant à partir du fichier, il sera omis des résultats.

24
hyperslug

UTILISATION CSVKIT :

csvjoin -c email id_email.csv email_name.csv

ou alors

csvjoin -c 2,1 id_email.csv email_name.csv
26
Tgr

Peut-être est-il surchargé, mais vous pouvez importer dans une base de données (E.G. OpenOffice Base) comme deux types de tables et définir un rapport qui est la sortie souhaitée.

Si l'importation CSV est un problème, un programme de tableur (E.G. OpenOffice Calc) peut faire l'importation. Le résultat peut alors facilement être transféré dans la base de données.

6
Peter Mortensen

En tant que référence future, vous voudrez peut-être commencer à jouer avec AWK . C'est un petit langage de script très simple qui existe sous une forme sur chaque système * NIX et sa seule mission est la vie est la manipulation de bases de données textuelles délimitées standard. Avec quelques lignes de script jetables, vous pouvez faire des choses très utiles. La langue est petite et élégante et a un meilleur rapport utilitaire/complexité que tout ce que je suis au courant.

4
jim in austin

Essayez Cruncher CSV .

Il prend des fichiers CSV sous forme de tables SQL, puis permet aux requêtes SQL, ce qui entraîne un autre fichier CSV ou JSON.

Pour votre cas, vous appelez simplement:

crunch -in tableA.csv tableB.csv -out output.csv \
   "SELECT tableA.id, tableA.email, tableB.name 
    FROM tableA LEFT JOIN tableB USING (email)"

L'outil a besoin Java 8 ou ultérieure.

Quelques avantages:

  • Vous obtenez vraiment un support CSV, pas seulement "supposons que les données sont correctes".
  • Vous pouvez vous joindre à plusieurs clés.
  • Plus facile à utiliser et à comprendre que les solutions basées sur join.
  • Vous pouvez combiner plus de 2 fichiers CSV.
  • Vous pouvez vous joindre à SQL Expressions - les valeurs ne doivent pas nécessairement être les mêmes.

Disclaimer: J'ai écrit cet outil. Auparavant, il était en désordre après la fermeture du code de Google, mais j'ai réécuté et ajouté de nouvelles fonctionnalités que je l'utilise.

0
Ondra Žižka

Dans Bash 5.0.3 avec =GNU Coreutils 8.30 et construit de La réponse de Hyperslug :

Si vous avez des fichiers CSV non traités avec des lignes en double et que vous ne voulez pas omettre des données en raison d'un champ manquant dans une ligne de file1.csv ou file2.csv, vous pouvez procéder comme suit:

Trier le fichier 1 par champ 2 et trier le fichier 2 par champ 1:

( head -n1 file1.csv && tail -n+2 file1.csv | sort -t, -k2,2 ) > sort1.csv
( head -n1 file2.csv && tail -n+2 file2.csv | sort -t, -k1,1 ) > sort2.csv

Élargir sur les paramètres de Hyperslug:

-k 2,2     : character sort starting and stopping on 2nd field
-k 1,1     : character sort starting and stopping on 1st field
head -n1   : read first line
tail -n+1: : read all but first line
(  )       : subshell
>          : output to file

Je devais faire head et tail dans le sous-groupe ( ) afin de préserver la première ligne d'en-tête du fichier CSV Quand Tri par un champ donné .

Puis,

join -t , -a1 -a2 -1 2 -2 1 -o auto sort1.csv sort2.csv > sort3.csv

Élargir sur les paramètres de Hyperslug:

-t ,    : ',' is the field separator
-a1     : Do not omit lines from file 1 if no match in file 2 found
-a2     : Do not omit lines from file 2 if no match in file 1 found.
-1 2    : file 1, 2nd field
-2 1    : file 2, 1st field
-o auto : Auto format: includes extra commas indicating unmatched fields
>       : output to file

Voici un exemple file1.csv, file2.csv et le résultat sort3.csv:

file1.csv:

ID,email
02,[email protected]
03,[email protected]
05,[email protected]
07,[email protected]
11,[email protected]

file2.csv:

email,name
[email protected],Timothy Brown
[email protected],Robert Green
[email protected],Raul Vasquez
[email protected],Carol Lindsey

sort3.csv:

email,ID,name
[email protected],02,Robert Green
[email protected],,Carol Lindsey
[email protected],03,
[email protected],07,Raul Vasquez
[email protected],05,
[email protected],,Timothy Brown
[email protected],11,

Vous pouvez voir Timothy Brown et Carol Lindsey Manque IDS, mais sont toujours inclus dans le fichier CSV joint (avec leurs noms et emails dans les champs appropriés).

0
baltakatei

Vous pouvez lire le fichier CSV avec un programme de tableur comme LibreOffice et utiliser VLOOKUP() Macro pour rechercher le nom dans le deuxième fichier.

0
Janek

Utilisez Go: https://github.com/chrislusf/gleam

package main

import (
    "flag"
    "os"

    "github.com/chrislusf/gleam"
    "github.com/chrislusf/gleam/source/csv"
)

var (
    aFile = flag.String("a", "a.csv", "first csv file with 2 fields, the first one being the key")
    bFile = flag.String("b", "b.csv", "second csv file with 2 fields, the first one being the key")
)

func main() {

    flag.Parse()

    f := gleam.New()
    a := f.Input(csv.New(*aFile))
    b := f.Input(csv.New(*bFile))

    a.Join(b).Fprintf(os.Stdout, "%s,%s,%s\n").Run()

}
0
chrislusf