Додайте стовпчик з одного .csv до іншого .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

бажаний вихід.csv

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

Я намагався безрезультатно використовувати "приєднатися" та "вставити". Чи є команда bash для цього? Стовпець "А" однаковий в обох .csvфайлах.


Отже, ви просите скопіювати стовпець B у файл 1? Або стовпці C і D у файл2?
Тім

Будь-який спосіб буде добре, поки вихід відповідає "бажаному виходу.csv"
Roboman1723

Я додав нову відповідь, яка, я думаю, простіше, ніж усі інші відповіді (моя перша відповідь включена). Можливо, ви захочете прийняти це так, щоб інформація для подальшого використання була легко знайдена.
don.joey

Відповіді:


11

З єдиною awkкомандою:

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

Отримайте рядок з file1 і збережіть його в локальну змінну f1, потім надрукуйте рядок, який зберігається в, f1і, нарешті, надрукуйте треті ( $3) і вперед ( $3) поля з файлу1, які повністю розділені комою ,, і змініть OFS (роздільник вивідного поля [пробіл від за замовчуванням]) до коми ( ,).


Коротка команда буде такою:

paste -d, file2 <(cut -d, -f3- file1)
 А Б В Г  
 А Б В Г  
 А Б В Г  
 А Б В Г  

вставити файл2, потім вирізати і вставити третій стовпець до наступного ( -f3-) з файлу1.


З awkі paste(варіант А)

Нижче команда також копіює останні два стовпці ( C,D) з файлу1 в кінці кожного рядка у файлі2:

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

Вище вставте вміст file2, потім надрукуйте роздільник комами ( -d','), потім вставте два останніх поля ( NFце індекс останнього поля і $NFце рядок, який є його індексом NF. Так $(NF-1)це друге поле перед останнім полем) з file1, коли цей індекс переосмислює або розбивається з комою глядача ( -F',').

З awkі paste(варіант B)

Ця команда також така ж, як і вище ( $3і $4вказує на третє і четверте поле кожного рядка з файлу1):

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

Або інше рішення з cutкомандою:

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

Команда cut у наведеній вище команді спочатку вирізає перше поле ( -f1яке індексується роздільником коми ( -d.)) з file1 ( cut -d, -f1 file1), потім вирізає та вставить друге поле file2 ( cut -d, -f2 file2) і, нарешті, вирізає та вставить третій стовпчик ( -f3) у параметри ( -) знову з file1 ( cut -d, -f3- file1).

Ця команда також повертає той самий результат:

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

вставити друге поле з file1 ( awk -F',' '{print $1}' file1), потім надрукувати кому ( -d,), потім вставити другий стовпчик з file2 ( awk -F',' '{print $2}' file2), нарешті знову вставити другий і останній стовпчик file1 ( awk -F',' '{print $3","$4}' file1).


@kasi ви могли це зробити через awk себе. Дивіться stackoverflow.com/a/14984673/3297613
Avinash Raj

9

Ось краса (я думаю):

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

Розбитий по кроках:

Крок 1. Встановіть csvkit:

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

Крок 2. Використовуйте команду приєднання разом із комою як роздільник

join -t,

Крок 3. Подайте йому фактичні стовпці, які ви хочете. Зверніть увагу, як ви подаєте його в перший стовпець двічі, тому що це саме те, на чому насправді виконується з'єднання (поведінка за замовчуванням join).

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

або коротко:

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

Ви можете перенаправити цей стандартний вихід у файл (бажаний вихід), якщо потрібно.

Переваги

Цей спосіб має ряд переваг перед іншими, запропонованими.

Перше і головне: воно виконує справжнє з'єднання. Це означає, що його можна використовувати і для більш складних даних. Наприклад, дуже легко зробити приєднання в іншому полі. Це не просто дивиться на позицію поля, але це дійсно враховує колонку. Він фактично працює з форматом даних (csv) і не трактує його як текст.

По-друге, він використовує дуже потужний інструментарій csv, який також дозволяє a) відображати статистику за допомогою однієї команди ( csvstats), b) перевіряти чисті дані ( csvclean), а також перетворювати їх у json, sql або навіть завантажувати їх у пітон! Цей інструментарій широко використовується в науці даних для підготовки даних.


Якщо ви встановлюєте на Ubuntu, можливо, вам доведеться встановити заголовки розробки Python до встановлення csvkit: sudo apt-get install python-dev python-pip python-setuptools build-essential- посилання
karel

Дивовижна відповідь також, я працюю на сервері компанії, тому на встановлення матеріалів потрібно близько тижня паперової роботи. Працює на моїй машині, хоча!
Roboman1723

+1 для показу мені іншого інструменту для CSV-даних. Окреме запитання, але чи знаєте ви окремого розробника звітів для файлів даних CSV?
Джо

@Joe, чи можете ви бути більш конкретними щодо того, що ви маєте на увазі, коли ви говорите про «письменника-звіту»? Я не впевнений, що розумію, що ти маєш на увазі.
don.joey

Я розмістив окреме запитання на unix.stackexchange.com/questions/170199/…
Джо

7

Ось ще одна прекрасна. Я думаю, що це найпростіша з усіх пропозицій, поки що.

csvtool pastecol 2 2 file1.csv file2.csv

Якщо ви ще не встановили csvtool, ви повинні sudo apt-get install csvtool.

З документів:

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

Замініть вміст стовпців, на які посилається у файлі input.csv, на один із відповідних стовпців, вказаних у update.csv.

Приклад:

  csvtool pastecol 2-3 1- input.csv update.csv.csv > output.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

Об'єднання двох файлів:

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

Що ви по суті робите, це вставити другий file2.csvстовпчик, як стовпець 2 в file1.csv.

Зауважте, що це також працює на тому ж документі. Якщо ви хочете поміняти місцями два стовпці, ви можете зробити це, використовуючи той самий файл, що і input.csv та update.vsc.

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

Без сумніву, найелегантніший.
Яків Влійм

2

Щоб перемістити вибрану кількість стовпців з одного файлу в інший:

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

з двох файлів:

файл_1

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

файл_2

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

Коли ви встановите cols = 1:

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

Але коли ви встановите 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

Як використовувати

Скопіюйте його в порожній файл, вказати шлях до file1, file2а число стовпців , щоб перемістити, зберегти його , як move.pyі запустити його:

python3 /path/to/move.py

Також можна додати один або кілька стовпців із середини стовпців вихідного файлу таким чином.


Хотів би побачити, як ти користуєшся import csv.
don.joey

@ don.joey Дякую за пропозицію, обов'язково вивчимо її.
Яків Влійм

0

Ще один метод в python через модуль 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))

Щоб запустити вищезазначений сценарій,

python3 script.py file1 file2

Вихід:

A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.