Adicionar coluna de um arquivo .csv a outro arquivo .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

Output.csv desejado

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

Eu tentei usar "ingressar" e "colar" sem sucesso. Existe um comando bash para fazer isso? A coluna "A" é a mesma nos dois .csvarquivos.

Roboman1723
fonte
Então você está pedindo para copiar a coluna B para o arquivo 1? Ou colunas C e D para o arquivo2?
Tim
De qualquer maneira seria muito bem contanto que a saída corresponde "desiredOutput.csv"
Roboman1723
Eu adicionei uma nova resposta que, eu acho, é mais fácil do que todas as outras respostas (minha primeira resposta incluída). Você pode considerar aceitar isso para que, para referência futura, as informações sejam facilmente encontradas.
don.joey

Respostas:

11

Com apenas o awkcomando:

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

Obtenha uma linha do arquivo1 e armazene-a na variável local f1, depois imprima a linha armazenada f1e, finalmente, imprima o terceiro ( $3) e o dianteiro ( $3) campos do arquivo1 que delimitou por vírgula por ,completo e altere o OFS (separador do campo de saída [espaço por padrão]) para vírgula ( ,).


O comando curto seria assim:

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

cole o arquivo2, recorte e cole a terceira coluna na próxima ( -f3-) do arquivo1.


Com awke paste(opção A)

O comando abaixo também copia as duas últimas colunas ( C,D) do arquivo1 no final de cada linha do arquivo2:

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

Acima do comando, cole o conteúdo do arquivo2, imprima um delimitador de vírgula ( -d',') e, em seguida, cole os dois últimos campos ( NFé o índice do último campo e $NFa cadeia de caracteres que é o seu índice NF. Assim $(NF-1)é o segundo campo antes do último campo) do arquivo1 quando esse índice redefine ou divide com vírgula espectador ( -F',').

Com awke paste(opção B)

Este comando também é o mesmo que acima ( $3e $4aponta para o terceiro e o quarto campos de cada linha do arquivo1):

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

Ou outra solução com o cutcomando:

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

comando cut no comando acima, primeiro corte o primeiro campo ( -f1indexado com delimitador de vírgula ( -d.)) de file1 ( cut -d, -f1 file1), depois corte e cole o segundo campo de file2 ( cut -d, -f2 file2) e, finalmente, corte e cole a terceira coluna ( -f3) nos nexts ( -) do arquivo1 ( cut -d, -f3- file1) novamente.

Este comando também retorna o mesmo resultado:

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

cole o segundo campo de file1 ( awk -F',' '{print $1}' file1), imprima uma vírgula ( -d,), cole a segunda coluna de file2 ( awk -F',' '{print $2}' file2) e, finalmente, cole a segunda e a última coluna de file1 ( awk -F',' '{print $3","$4}' file1) novamente.

αғsнιη
fonte
@ kasi você pode fazer isso através do próprio awk. Veja stackoverflow.com/a/14984673/3297613
Avinash Raj
9

Aqui está uma beleza (eu acho):

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

Dividido em etapas:

Etapa 1. Instale o csvkit:

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

Etapa 2. Use o comando join com uma vírgula como separador

join -t,

Etapa 3. Alimente as colunas reais que você deseja. Observe como você alimenta a primeira coluna duas vezes, porque é aquela na qual a junção é realmente executada (comportamento padrão de join).

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

ou em forma abreviada:

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

Você pode redirecionar essa saída padrão para um arquivo (Saída desejada), se desejado.

Vantagens

Este método tem várias vantagens sobre os outros propostos.

Em primeiro lugar: realiza uma junção real. Isso significa que também pode ser usado para dados mais complexos. É muito fácil fazer uma junção em outro campo, por exemplo. Ele não olha simplesmente para a posição do campo, mas realmente leva a coluna em consideração. Na verdade, ele funciona com o formato dos dados (csv) e não o trata como texto.

Segundo, ele usa o muito poderoso kit de ferramentas csv, que também permite: a) exibir estatísticas com um comando ( csvstats), b) verificar se os dados estão limpos ( csvclean), mas também transformá-los em json, sql ou carregá-los no Pitão! Este kit de ferramentas é muito usado em ciência de dados para preparação de dados.

don.joey
fonte
Se você estiver instalando no Ubuntu, pode ser necessário instalar os cabeçalhos de desenvolvimento Python antes de instalar o csvkit: sudo apt-get install python-dev python-pip python-setuptools build-essential- link
karel
Ótima resposta, também, estou trabalhando em um servidor da empresa, para instalar coisas que levam cerca de uma semana de trabalho em papel. Funciona na minha máquina!
Roboman1723
+1 por me mostrar outra ferramenta para dados CSV. Pergunta separada, mas você conhece um gravador de relatório independente para arquivos de dados CSV?
31414 Joe
@ Joe, você pode ser mais específico sobre o que quer dizer quando fala de um 'redator de relatórios'? Não sei ao certo o que você quer dizer.
don.joey
Eu postei uma pergunta separada em unix.stackexchange.com/questions/170199/…
Joe Joe
7

Aqui está outro lindo. Eu acho que é a mais fácil de todas as sugestões, até agora.

csvtool pastecol 2 2 file1.csv file2.csv

Se você não instalou o csvtool no passado, precisará instalá-lo sudo apt-get install csvtool.

Dos documentos:

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

Substitua o conteúdo das colunas referenciadas no arquivo input.csv pelo da coluna correspondente especificada em update.csv.

Exemplo:

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

Observe como, no nosso caso, estamos substituindo as segundas colunas dos arquivos.

Exemplos

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 os dois arquivos:

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

O que você basicamente faz é colar a coluna dois file2.csvcomo coluna 2 em file1.csv.

Observe que isso também funciona no mesmo documento. Se você deseja trocar duas colunas, pode fazê-lo usando o mesmo arquivo que input.csv e update.vsc.

csvtool pastecol 2 1 file2.csv file2.csv 
A,A
A,A
A,A 
A,A
don.joey
fonte
Sem dúvida, o mais elegante.
27614 Jacob Vlijm
2

Para mover um número escolhido de colunas de um arquivo para outro:

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

de dois arquivos:

arquivo_1

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

arquivo_2

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

Quando você define cols = 1:

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

Mas quando você define 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

Como usar

Copiá-lo em um arquivo vazio, definir o caminho para file1, file2e o número de colunas para mover, guardá-lo como move.pye executá-lo por:

python3 /path/to/move.py

Também é possível adicionar uma ou mais colunas do meio das colunas do arquivo de origem dessa maneira.

Jacob Vlijm
fonte
Teria adorado ver você usar import csvembora.
don.joey
@ don.joey Obrigado pela sugestão, com certeza vai dar uma olhada nela.
Jacob Vlijm
0

Outro método em python através do módulo 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))

Para executar o script acima,

python3 script.py file1 file2

Resultado:

A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D
Avinash Raj
fonte