Aggiungi colonna da un .csv a un altro file .csv


12

File1.csv

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

File2.csv

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

desiderato Output.csv

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

Ho provato a utilizzare "join" e "incolla" senza alcun risultato. C'è un comando bash per farlo? La colonna "A" è la stessa in entrambi i .csvfile.


Quindi stai chiedendo di copiare la colonna B nel file 1? O le colonne C e D in file2?
Tim

Ad ogni modo andrebbe bene fintanto che l'output corrisponderà a "desiderataOutput.csv"
Roboman1723

Ho aggiunto una nuova risposta che, a mio avviso, è più semplice di tutte le altre risposte (inclusa la mia prima risposta). Potresti prendere in considerazione l'idea di accettarlo in modo che per riferimento futuro le informazioni siano facilmente reperibili.
don.joey,

Risposte:


11

Con solo awkcomando:

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

Prendi una riga da file1 e salvala nella variabile locale f1, quindi stampa la riga che ha archiviato f1e infine stampa il terzo ( $3) e avanti ( $3) campi da file1 che delimitato da una virgola del ,tutto, e cambia OFS (output field separator [space by default]) in virgola ( ,).


Il comando breve sarebbe così:

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

incolla il file2, quindi taglia e incolla la terza colonna nella successiva ( -f3-) da file1.


Con awke paste(opzione A)

Il comando seguente copia anche le ultime due colonne ( C,D) da file1 alla fine di ogni riga in file2:

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

Sopra il comando incolla il contenuto di file2 quindi stampa un delimitatore virgola ( -d',') quindi incolla gli ultimi due campi ( NFè l'indice dell'ultimo campo ed $NFè la stringa che è il suo indice NF. Così $(NF-1)è il secondo campo prima dell'ultimo campo) da file1 quando quell'indice ridefinisce o si divide con virgola spettatore ( -F',').

Con awke paste(opzione B)

Anche questo comando è uguale al precedente ( $3e $4punta al terzo e quarto campo di ogni riga del file1):

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

O un'altra soluzione con cutcomando:

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

comando taglia sopra comando prima taglia il primo campo ( -f1che è indicizzato con delimitatore virgola ( -d.)) da file1 ( cut -d, -f1 file1), quindi taglia e incolla il secondo campo di file2 ( cut -d, -f2 file2) e infine taglia e incolla la terza colonna ( -f3) in nexts ( -) da file1 ( cut -d, -f3- file1) di nuovo.

Questo comando restituisce anche lo stesso risultato:

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

incolla il secondo campo da file1 ( awk -F',' '{print $1}' file1) quindi stampa una virgola ( -d,), quindi incolla la seconda colonna da file2 ( awk -F',' '{print $2}' file2), infine incolla awk -F',' '{print $3","$4}' file1nuovamente la seconda e ultima colonna di file1 ( ).


@kasi potresti farlo attraverso awk stesso. Vedi stackoverflow.com/a/14984673/3297613
Avinash Raj

9

Ecco una bellezza (penso):

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

Suddiviso per fasi:

Passaggio 1. Installa csvkit:

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

Passaggio 2. Utilizzare il comando join con una virgola come separatore

join -t,

Passaggio 3. Alimenta le colonne effettive che desideri. Nota come la nutri la prima colonna due volte, perché quella è quella su cui viene effettivamente eseguito il join (comportamento predefinito di join).

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

o in stenografia:

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

Se lo si desidera, è possibile reindirizzare l'output standard su un file (output desiderato).

vantaggi

Questo metodo presenta numerosi vantaggi rispetto agli altri proposti.

Innanzitutto: esegue un vero join. Ciò significa che può essere utilizzato anche per dati più complessi. È molto semplice fare un join su un altro campo, ad esempio. Non guarda semplicemente alla posizione del campo, ma prende davvero in considerazione la colonna. In realtà funziona con il formato dei dati (csv) e non lo tratta come testo.

In secondo luogo, utilizza il potente toolkit csv che consente anche di a) visualizzare le statistiche con un comando ( csvstats), b) verificare se i dati sono puliti ( csvclean), ma anche di trasformarli in json, in sql o persino caricarli in pitone! Questo toolkit è ampiamente utilizzato nella scienza dei dati per la preparazione dei dati.


Se stai installando su Ubuntu potresti dover installare le intestazioni di sviluppo di Python prima di installare csvkit: sudo apt-get install python-dev python-pip python-setuptools build-essential- link
karel

Ottima risposta, sto lavorando su un server aziendale, quindi l'installazione di roba richiede circa una settimana di lavoro di ufficio. Funziona sulla mia macchina però!
Roboman1723,

+1 per avermi mostrato un altro strumento per i dati CSV. Domanda separata, ma conosci un autore autonomo di report per file di dati CSV?
Joe,

@Joe puoi essere più specifico su cosa intendi quando parli di un 'autore di report'? Non sono sicuro di capire cosa intendi.
don.joey,

Ho pubblicato una domanda separata su unix.stackexchange.com/questions/170199/…
Joe,

7

Eccone un altro bellissimo. Penso che sia il più semplice di tutti i suggerimenti, finora.

csvtool pastecol 2 2 file1.csv file2.csv

Se non hai già installato csvtool in passato, devi farlo sudo apt-get install csvtool.

Dai documenti:

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

Sostituisci il contenuto delle colonne a cui fa riferimento il file input.csv con quello della colonna corrispondente specificata da in update.csv.

Esempio:

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

Nota come nel nostro caso stiamo sostituendo le seconde colonne dei file.

Esempi

File1.csv

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

File2.csv

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

Combinando i due file:

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

Quello che essenzialmente fai è incollare la colonna due file2.csvcome colonna 2 in file1.csv.

Nota che questo funziona anche sullo stesso documento. Se si desidera scambiare due colonne, è possibile farlo utilizzando lo stesso file di input.csv e update.vsc.

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

Senza dubbio il più elegante.
Jacob Vlijm,

2

Per spostare un numero selezionato di colonne da un file a un altro:

#!/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:]))

da due file:

file_1

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

file_2

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

Quando si imposta cols = 1:

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

Ma quando si imposta 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

Come usare

Copiarlo in un file vuoto, impostare il percorso file1, file2e il numero di colonne per spostare, salvarlo come move.pyed eseguirlo da:

python3 /path/to/move.py

In questo modo è anche possibile aggiungere una o più colonne dal centro delle colonne del file sorgente.


Mi sarebbe piaciuto vederti usare import csvperò.
don.joey,

@ don.joey Grazie per il suggerimento, lo esaminerò sicuramente.
Jacob Vlijm,

0

Un altro metodo in Python attraverso il modulo 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))

Per eseguire lo script sopra,

python3 script.py file1 file2

Produzione:

A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.