13 votes

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

File1.csv

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

file2.csv

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

desired Output.csv

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

J'ai essayé d'utiliser "join" et "paste" sans succès. Existe-t-il une commande bash pour faire cela ? La colonne "A" est la même dans les deux fichiers .csv.

12voto

αғsнιη Points 33236

Avec seulement la commande awk :

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

Obtenez une ligne de file1 et stockez-la dans la variable locale f1, puis affichez la ligne stockée dans f1 et enfin affichez le troisième($3) et le quatrième($3) champs de file1 qui sont délimités par des virgules ,, et changez le OFS(séparateur de champ de sortie [espace par défaut]) en virgule(,).


La commande courte serait la suivante :

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

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

copiez le file2, puis coupez et collez la troisième colonne à la suite(-f3-) de file1.


Avec awk et paste (option A)

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

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

La commande ci-dessus colle le contenu de file2 puis imprime un délimiteur de virgule(-d',') puis colle 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) de file1 quand ces index se redéfinissent ou se séparent avec un observateur de virgule(-F',').

Avec awk et paste (option B)

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

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)

La commande cut dans la commande ci-dessus coupe d'abord le premier champ(-f1 indexé avec un délimiteur de virgule(-d)) de file1(cut -d, -f1 file1), puis coupe et colle le deuxième champ de file2(cut -d, -f2 file2) et enfin coupe et colle la troisième colonne(-f3) aux suivants(-) de file1(cut -d, -f3- file1) à nouveau.

Cette commande retourne é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 le deuxième champ de file2(awk -F',' '{print $2}' file2), enfin collez le deuxième et dernier champ de file1(awk -F',' '{print $3","$4}' file1) à nouveau.

9voto

don.joey Points 26933

Voici une beauté (je pense):

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

Décomposé en é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. Envoyez-lui les colonnes que vous voulez réellement. Notez comment vous envoyez 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 abrégé:

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

Vous pouvez rediriger la sortie standard vers un fichier (desiredOutput) si vous le souhaitez.

Avantages

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

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

Ensuite, elle utilise le très puissant toolkit csv qui permet également a) d'afficher des statistiques avec une seule commande (csvstats), b) de vérifier si les données sont propres (csvclean), mais aussi de les transformer en json, en sql, voire de les charger dans python! Ce toolkit est largement utilisé en science des données pour la préparation des données.

8voto

don.joey Points 26933

Voici un autre bel exemple. Je pense que c'est la suggestion la plus facile jusqu'à présent.

csvtool pastecol 2 2 file1.csv file2.csv

Si vous n'avez pas encore installé csvtool, vous devez sudo apt-get install csvtool.

À partir de la documentation :

pastecol   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

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

Exemples

file1.csv

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

file2.csv

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

Combinaison des 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, c'est coller la colonne deux de file2.csv en tant que colonne 2 dans file1.csv.

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

csvtool pastecol 2 1 file2.csv file2.csv 
A,A
A,A
A,A 
A,A

2voto

Jacob Vlijm Points 78990

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 :

file_1

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

file_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 vers file1, file2 et le nombre de colonnes à déplacer, enregistrez-le sous move.py et exécutez-le via :

python3 /path/to/move.py

Il est également possible d'ajouter une ou plusieurs colonnes au milieu des colonnes du fichier source de cette manière.

0voto

Avinash Raj Points 72686

Un autre méthode en python à travers 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

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X