включайся в bash как в SAS - PullRequest
3 голосов
/ 12 января 2012

Я бы хотел объединить два файла в bash , используя общий столбец. Я хочу сохранить как все допустимые, так и невыгодные строки из обоих файлов. К сожалению, используя join, я мог сохранить непоправимые поля только из одного файла, например. join -1 1 -2 2 -a1 -t" ".
Я также хотел бы сохранить все пары для повторяющихся записей (в столбце соединения) из обоих файлов. То есть Если file1
x id1 a b
x id1 c d
x id1 d f
x id2 c x
x id3 f v

и второй файл

id1 df cf
id1 ds dg
id2 cv df
id2 as ds
id3 cf cg

результирующий файл должен быть:

x id1 a b df cf
x id1 a b ds dg
x id1 c d df cf
x id1 c d ds dg
x id1 d f df cf
x id1 d f ds dg
x id2 c x cv df
x id2 c x as ds
x id3 f v cf cg

Вот почему я всегда использую SAS для такого объединения после сортировки соответствующих столбцов.

data x;
merge file1 file2;
by common_column;
run;

Работает нормально, но
1. , так как большую часть времени я пользуюсь Ubuntu, мне нужно переключиться на Windows, чтобы объединить данные в SAS.
2. самое главное SAS может усекать слишком длинные записи данных.

Вот почему я предпочитаю присоединять мои файлы в bash, но я не знаю подходящей команды.
Может ли кто-нибудь мне помочь или направить меня на соответствующий ресурс?

Ответы [ 2 ]

4 голосов
/ 12 января 2012

Согласно справочной странице join, -a <filenum> сохраняет все негодные строки из файла <filenum> (1 или 2).Итак, просто добавьте -a1 -a2 в вашу командную строку, и все готово.Например:

# cat a
1 blah
2 foo

# cat b
2 bar
3 baz

# join -1 1 -2 1 -t" " a b
2 foo bar

# join -1 1 -2 1 -t" " -a1 a b
1 blah
2 foo bar

# join -1 1 -2 1 -t" " -a2 a b
2 foo bar
3 baz

# join -1 1 -2 1 -t" " -a1 -a2 a b
1 blah
2 foo bar
3 baz

Это то, что вы искали?

Редактировать:

Поскольку вы предоставили более подробную информацию, вот какпроизведите желаемый результат (обратите внимание, что мой файл a - ваш первый файл, а мой файл b - ваш второй файл. Мне пришлось повернуть -1 -1 -2 2 до -1 2 -2 1, чтобы присоединиться к идентификатору).Я также добавил список полей для форматирования вывода - обратите внимание, что в нем поле соединения «0»:

# join -1 2 -2 1 -o 1.1,0,1.3,1.4,2.2,2.3 a b

производит то, что вы дали.Добавьте -a1 -a2, чтобы сохранить негодные строки из обоих файлов, затем вы получите еще две строки (вы можете угадать мои тестовые данные из них):

x id4 u t
 id5   ui oi

Что довольно нечитабельно, поскольку любое пропущенное поле является простопространство.Итак, давайте заменим их на '-', что приведет к:

# join -1 2 -2 1 -a1 -a2 -e- -o 1.1,0,1.3,1.4,2.2,2.3 a b
x id1 a b df cf
x id1 a b ds dg
x id1 c d df cf
x id1 c d ds dg
x id1 d f df cf
x id1 d f ds dg
x id2 c x cv df
x id2 c x as ds
x id3 f v cf cg
x id4 u t - -
- id5 - - ui oi
1 голос
/ 12 января 2012

Если команда join недостаточно мощная, я обычно использую sqlite , если мне нужно выполнить такие операции в оболочке.

Вы можете легко импортировать плоские файлы в таблицы, затем выполните SQL SELECT с правильным JOIN.

Обратите внимание, что с sqlite вы можете использовать index , чтобы объединение было даже быстрее .

sqlite3 << EOF!
CREATE TABLE my table1 (.... -- define your table here
CREATE TABLE my table2 (.... -- define your table here
.separator "," -- define input field separator here if needed
.import input_file.txt mytable1
.import input_file.txt mytable2
SELECT ... JOIN ...
EOF!

sqlite является бесплатным и mutiplatform.Очень удобно.

...