Добавить столбец из одного .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

желаемый Output.csv

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

Я пытался использовать "присоединиться" и "вставить" безрезультатно. Для этого есть команда bash? Колонка «А» одинакова в обоих .csvфайлах.


Итак, вы просите скопировать столбец B в файл 1? Или столбцы C и D в file2?
Тим

В любом случае все будет в порядке, если выходные данные соответствуют «selectedOutput.csv»
Roboman1723

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

Ответы:


11

С единственной awkкомандой:

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

Получите строку из file1 и сохраните ее в локальной переменной f1, затем напечатайте строку, которая была сохранена в, f1и, наконец, напечатайте третье ( $3) и forward ( $3) поля из file1, которые разделены запятой ,, и измените OFS (разделитель выходного поля [пробел по по умолчанию]) до запятой ( ,).


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

paste -d, file2 <(cut -d, -f3- file1)
 А, В, С, D  
 А, В, С, D  
 А, В, С, D  
 А, В, С, D  

вставьте файл2, затем вырежьте и вставьте третий столбец в следующий ( -f3-) из файла1.


С awkи paste(вариант А)

Команда ниже также копирует последние два столбца ( C,D) из файла file1 в конце каждой строки в файле file2:

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

Выше команды вставьте содержимое file2, затем напечатайте запятую delimiter ( -d','), затем вставьте два последних поля ( NFэто индекс последнего поля и $NFявляется строкой, которой является его индекс NF. Так же $(NF-1)как и второе поле перед последним полем) из file1, когда эти индексы переопределяются или разделяется с запятой зрителя ( -F',').

С awkи paste(вариант Б)

Эта команда также является такой же, как указано выше ( $3и $4указывает на третье и четвертое поле каждой строки из file1):

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) в nexts ( -) из 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
Авинаш Радж

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, который также позволяет а) отображать статистику с помощью одной команды ( csvstats), б) проверять, являются ли данные чистыми ( csvclean), а также преобразовывать их в json, в sql или даже загружать в питон! Этот инструментарий широко используется в науке о данных для подготовки данных.


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

Хороший ответ, я работаю на корпоративном сервере, так что установка занимает около недели бумажной работы. Работает на моей машине, хотя!
Roboman1723

+1 за показ мне еще один инструмент для данных CSV. Отдельный вопрос, но знаете ли вы отдельного автора отчетов для файлов данных CSV?
Джо

@ Джо, можешь ли ты быть более конкретным о том, что ты имеешь в виду, когда говоришь о «составителе отчетов»? Я не уверен, что понимаю, что вы имеете в виду.
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столбец 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:]))

из двух файлов:

file_1

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

file_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.