2016-08-03 4 views
0

У меня есть следующая проблема.Создайте diff между двумя файлами на основе определенного столбца

Скажем, у меня есть 2 файла:

a.txt

1 A1 
2 A2 

b.txt

1 B1 
2 B2 
3 B3 

Я хочу сделать диф, который основан только на значениях первого столбца, так результат должен быть

3  B3 

Как эта проблема может быть решена с помощью bash в linux?

ответ

3

[ awk ] ваш друг

awk 'NR==FNR{f[$1];next}{if($1 in f){next}else{print}}' A.txt B.txt 

или более просто

awk 'NR==FNR{f[$1];next}!($1 in f){print}' A.txt B.txt 

или даже более просто

awk 'NR==FNR{f[$1];next}!($1 in f)' A.txt B.txt 

Немного объяснение гр ertainly помочь

  1. NR & FNR являются AWK встроенными переменными, которые стоят за total number of records - including current - processed so farиtotal number of records - including current - processed so far in the current fileсоответственно и они будут равны только для первого обработанного файла.

  2. 10 сначала создает массив f, а затем добавляет $1 в качестве ключа, если тот же ключ еще не существует. Если значение не присвоено, тогда f [$ 1] автоматически инициализируется до нуля, но этот аспект не используется в вашем случае

  3. next переходит к следующей записи без обработки остальной части awk-скрипта.

  4. Обратите внимание, что часть {if($1 in f){next}else{print}} будет обрабатываться только для второго (и последующего, если есть) файла/с.
  5. $1 in f проверяет, является ли ключ $1 существует в массиве f
  6. if-else-print часть само за себя.
  7. Замечание в третьей версии, {print} опущено, по умолчанию действие по умолчанию для awk - это печать!

+1

или более просто 'AWK«NR == FNR { f [$ 1]; next}! ($ 1 in f) '' – 123

+0

@ 123: Держу пари, что ты в этом хорош. :) Спасибо, добавь его в решение – sjsam

0

Как это bash, но только если вы действительно не заинтересованы во второй колонке на всех:

diff <(cut -f1 -d" " A.txt) <(cut -f1 -d" " B.txt) 
2
awk 'NR==FNR{array[$1];next} !($1 in array)' a.txt b.txt 
3 B3 
Смежные вопросы