web-dev-qa-db-fra.com

Ajouter une colonne d'un fichier .csv à un autre fichier .csv

fichier1.csv

A,,C,D
A,,C,D
A,,C,D
A,,C,D

fichier2.csv

A,B
A,B
A,B
A,B

output.csv souhaité

A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D

J'ai essayé d'utiliser "rejoindre" et "coller" en vain. Existe-t-il une commande bash pour le faire? La colonne "A" est identique dans les deux fichiers .csv.

12
Roboman1723

Avec uniquement la commande awk:

awk -F, '{getline f1 <"file2" ;print f1,$3,$4}' OFS=, file1

Récupérez une ligne de fichier1 et stockez-la dans la variable locale f1, puis imprimez la ligne stockée dans f1 et imprimez enfin les troisièmes ($3) et suivis ($3) de fichier1 délimités par la virgule ,, puis modifiez le OFS (sortie). séparateur de champs [espace par défaut]) en virgule (,).


La commande courte serait comme ceci:

paste -d, file2 <(cut -d, -f3- file1)
 A, B, C, D 
 A, B, C, D 
 A, B, C, D 
 A, B, C, D 

collez le fichier2, puis coupez et collez la troisième colonne dans la suivante (-f3-) à partir du fichier1.


Avec awk et paste (option A)

La commande ci-dessous copie également les deux dernières colonnes (C,D) de fichier1 à la fin de chaque ligne de fichier2:

paste -d',' file2  <(awk -F',' '{print $(NF-1)","$NF}' file1)

Au-dessus de la commande coller le contenu du fichier2, puis imprimez un séparateur de virgule (-d',') puis collez les deux derniers champs (NF est l'index du dernier champ et $NF est la chaîne dont l'index est NF. Donc $(NF-1) est le deuxième champ avant le dernier champ) à partir du fichier1 lorsque ces index sont redéfinis ou divisés avec une virgule spectateur (-F',').

Avec awk et paste (option B)

Cette commande est également la même que ci-dessus ($3 et $4 pointent vers les troisième et quatrième champs de chaque ligne de fichier1):

paste -d',' file2  <(awk -F',' '{print $3","$4}' file1)

Ou une autre solution avec la commande cut:

paste -d, <(cut -d, -f1 file1) <(cut -d, -f2 file2) <(cut -d, -f3- file1)

couper la commande dans la commande ci-dessus commence par couper le premier champ (-f1 indexé avec un séparateur de virgule (-d.)) à partir de fichier1 (cut -d, -f1 file1), puis couper et coller le deuxième champ de file2 (cut -d, -f2 file2) et enfin couper et Collez à nouveau la troisième colonne (-f3) dans les éléments suivants (-) à partir de fichier1 (cut -d, -f3- file1).

Cette commande renvoie également le même résultat:

paste -d, <(awk -F',' '{print $1}' file1) <(awk -F',' '{print $2}' file2) <(awk -F',' '{print $3","$4}' file1)

collez le deuxième champ de file1 (awk -F',' '{print $1}' file1), puis imprimez une virgule (-d,), puis collez la deuxième colonne de file2 (awk -F',' '{print $2}' file2), puis collez enfin la deuxième et dernière colonne de file1 (awk -F',' '{print $3","$4}' file1).

11
αғsнιη

Voici une beauté (je pense):

join -t, <(csvcut -c 1,3,4 file1.csv) <(csvcut -c 1,2 file2.csv)

Décomposé par étapes:

Étape 1. Installez csvkit:

Sudo pip install csvkit
Sudo apt-get install python-dev python-pip python-setuptools build-essential

Étape 2. Utilisez la commande join avec une virgule comme séparateur

join -t,

Étape 3. Donnez-lui les colonnes que vous voulez. Notez comment vous alimentez la première colonne deux fois, car c’est celle sur laquelle la jointure est réellement effectuée (comportement par défaut de join).

join -t, <(csvcut --columns 1,3,4 file1.csv) <(csvcut --columns 1,2 file2.csv)

ou en sténographie:

join -t, <(csvcut -c 1,3,4 file1.csv) <(csvcut -c 1,2 file2.csv)

Vous pouvez rediriger cette sortie standard vers un fichier (désirée) si vous le souhaitez.

Avantages

Cette méthode présente plusieurs avantages par rapport aux autres proposés.

D'abord et avant tout: il effectue une vraie jointure. Cela signifie qu'il peut également être utilisé pour des données plus complexes. Il est très facile de faire une jointure sur un autre champ, par exemple. Il ne se contente pas de regarder la position du champ, mais prend réellement en compte la colonne. Cela fonctionne réellement avec le format des données (csv) et ne les traite pas comme du texte.

Deuxièmement, il utilise le très puissant toolkit CSV qui vous permet également de: a) afficher des statistiques avec une commande (csvstats), b), vérifier si les données sont propres (csvclean), mais aussi les transformer en json, en sql ou même les charger en python! Cette boîte à outils est fortement utilisée en science des données pour la préparation des données.

9
don.joey

Voici une autre belle. Je pense que c'est la plus facile de toutes les suggestions, à ce jour.

csvtool pastecol 2 2 file1.csv file2.csv

Si vous n'avez pas déjà installé csvtool par le passé, vous devez Sudo apt-get install csvtool.

De la docs:

pastecol <column-spec1> <column-spec2> input.csv update.csv

Remplacez le contenu des colonnes référencées par dans le fichier input.csv par celui de la colonne correspondante spécifiée par dans update.csv.

Exemple:

  csvtool pastecol 2-3 1- input.csv update.csv.csv > output.csv

Notez comment, dans notre cas, nous remplaçons les deuxièmes colonnes des fichiers.

Exemples

fichier1.csv

A,,C,D
A,,C,D
A,,C,D
A,,C,D

fichier2.csv

A,B
A,B
A,B
A,B

Combinant les deux fichiers:

csvtool pastecol 2 2 file1.csv file2.csv
A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D

Ce que vous faites essentiellement consiste à coller la deuxième colonne de file2.csv en tant que colonne 2 dans file1.csv.

Notez que cela fonctionne également sur le même document. Si vous souhaitez échanger deux colonnes, vous pouvez le faire en utilisant le même fichier que input.csv et update.vsc.

csvtool pastecol 2 1 file2.csv file2.csv 
A,A
A,A
A,A 
A,A
7
don.joey

Pour déplacer un nombre choisi de colonnes d'un fichier à un autre:

#!/usr/bin/env python3

cols = 1; file_1 = "/path/to/file_1"; file_2 = "/path/to/file_2"

def readfile(file):
      with open(file) as src:
          return [item.strip().split(",") for item in src.readlines()]

file_1 = readfile(file_1); file_2 = readfile(file_2)

for i in range(len(file_1)):
    print((",").join(file_1[i]+file_2[i][-cols:]))

à partir de deux fichiers:

fichier_1

A,B
A,B
A,B
A,B

fichier_2

K,L,M
K,L,M
K,L,M
K,L,M

Lorsque vous définissez cols = 1:

A,B,M
A,B,M
A,B,M
A,B,M

Mais lorsque vous définissez cols = 2:

A,B,L,M
A,B,L,M
A,B,L,M
A,B,L,M

cols = 3:

A,B,K,L,M
A,B,K,L,M
A,B,K,L,M
A,B,K,L,M

Comment utiliser

Copiez-le dans un fichier vide, définissez le chemin sur file1, file2 et le nombre de colonnes à déplacer, enregistrez-le sous move.py et exécutez-le comme suit:

python3 /path/to/move.py

Il est également possible d'ajouter une ou plusieurs colonnes à partir du milieu des colonnes du fichier source de cette façon.

2
Jacob Vlijm

Une autre méthode dans python via le module csv.

script.py

#!/usr/bin/python3
import csv
import sys
file1 = sys.argv[1]
file2 = sys.argv[2]
with open(file2, 'r') as r:
    with open(file1, 'r') as f:
        csv_f = csv.reader(f)
        csv_r = csv.reader(r)
        bar = [linex for linex in csv_r]
        foo = [liney[2:] for liney in csv_f]
        zipped = Zip(bar,foo)
        result = [x+y for (x,y) in list(zipped)]
        for i in result:
            print(','.join(i))

Pour exécuter le script ci-dessus,

python3 script.py file1 file2

Sortie:

A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D
0
Avinash Raj