2013-11-19 2 views
1

У меня есть два файла, каждый из которых содержит один столбец:Вставить две колонки выпускающих пробелы, если соответствующее значение не найдено

x_a 
x_b 
x_d 
x_e 

и

y_a 
y_c 
y_e 

Что является лучшим способом для вставки два файла для того, чтобы получить результат, как

x_a y_a 
x_b 
     y_c 
x_d 
x_e y_e 

или даже

x_a y_a 
x_b ??? 
??? y_c 
x_d ??? 
x_e y_e 

Существует решение bash/awk/sed? Файлы имеют тысячи строк, а часть, которую я хочу проверить (a, b, c, d, e), представляет собой много строк чисел (на самом деле это координаты).

Заранее благодарю вас за помощь. Я попытался вставить в таблицу mysql и сделать соединение, но нет колонки.

EDIT: Все вопросы были быстрыми, полными и рабочими. Спасибо всем за ваше время

+1

Является ли заказ соответствующего выпуска? И вариант perl или python? – pfnuesel

+0

Нет, после того как будет возможно отсортировать их в некотором роде. –

+1

Отправлены ли файлы в том же порядке?Являются ли строки отсортированными по значению, которое вы хотите использовать для этого сравнения? –

ответ

4

Вот одно решение:

awk -F_ 'NR==FNR {x[$2]=$0;a[$2]=1;next} {y[$2]=$0;a[$2]=1} END {for (i in a) print x[i] "\t" y[i]}' file1 file2 
x_a  y_a 
x_b 
     y_c 
x_d 
x_e  y_e 

И ???

awk -F_ 'NR==FNR {x[$2]=$0;a[$2]=1;next} {y[$2]=$0;a[$2]=1} END {for (i in a) print (x[i]?x[i]:"???"),(y[i]?y[i]:"???")}' file1 file2 
x_a y_a 
x_b ??? 
??? y_c 
x_d ??? 
x_e y_e 

Как это работает?

awk -F_ '       # Field separator set to _ 
    NR==FNR {      # Run this on first file 
     x[$2]=$0     # Store line in array x, using field 2 as separator 
     a[$2]=1      # Store every unique separator in array a 
     next      # Next record 
     } 

     {       # Run this on second file 
     y[$2]=$0     # Store line in array y, using field 2 as separator 
     a[$2]=1      # Store every unique separator in array a 
     } 
    END {       # Do this at end 
     for (i in a)    # Read all unique value in array a 
      print x[i] "\t" y[i] # Print the array x and y using value in a 
     }' file1 file2    # Read the files 
+1

+1. Хорошая идея 'a [$ 2] = 1', чтобы получить полный список. На самом деле я почесывал голову. bdw просто 'a [$ 2]' также будет. – jkshah

+0

Можете ли вы немного уточнить свой код? – pfnuesel

+2

Спасибо, это всегда головоломка для решения этой комбинации нескольких файлов. – Jotne

2

Попробуйте AWK:

awk -F '_' 'NR==FNR {a[$2]=$0; next} $2 in a{print a[$2], $0; delete a[$2]; next} 
      !($2 in a){print "???", $0} END{for (i in a) print a[i], "???"}' f1 f2 
x_a y_a 
??? y_c 
x_e y_e 
x_d ??? 
x_b ??? 
1

Если вы считаете, используя MySQL - да, есть колонка в общем, однако, вам нужно создать его искусственно. Выполните команду: sed -e 's/_\(.*\)$/& \1/' на файл - вы получите выход, как:

x_a a 
x_b b 
x_d d 
x_e e 

2-й столбец можно использовать в качестве ключа соединения.

1

Это заставляет нас большую часть пути туда:

$ join -t_ -j 2 -o 1.1,1.2,2.1,2.2 -e " " -a1 -a2 file1 file2 
x_a_y_a 
x_b_ _ 
_ _y_c 
x_d_ _ 
x_e_y_e 

трубы через СЭД для удаления паразитного подчёркивания:

$ join -t_ -j 2 -o 1.1,1.2,2.1,2.2 -e " " -a1 -a2 file1 file2 | 
    sed 's/^\(._.\)_/\1 /;s/^ _/ /; s/ _ $//' 
x_a y_a 
x_b 
    y_c 
x_d 
x_e y_e 

Для вопросительных знаков, используйте sed 's/^\(._.\)_/\1 /;s/^ _ /???/; s/ _ $/???/'

join требует файлы, подлежащие сортировке по полю объединения, и в этом случае они есть. Если это не так:

$ join -t_ -j 2 -o 1.1,1.2,2.1,2.2 -e " " -a1 -a2 <(sort -t_ -k2,2 file1) <(sort -t_ -k2,2 file2) | 
    sed 's/^\(._.\)_/\1 /;s/^ _/ /; s/ _ $//' 
Смежные вопросы