Как удалить дублирующиеся строки в одном файле на основе общего поля между двумя файлами с помощью AWK? - PullRequest
2 голосов
/ 08 декабря 2010

У меня есть два файла

  1. Файл 1 содержит 3 поля

  2. Файл 2 содержит 4 поля

Количество строк в файле 1 намного меньше, чем в файле 2

Я хотел бы сравнить два файла на основе 1-го поля с помощью следующей операции

Еслипервое поле в любой строке файла 1 появляется в первом поле строки в файле 2, не печатайте эту строку для файла 2.

Любой совет будет благодарен.

Input File 1

 S13109 3739 31082 
 S45002 3800 31873 
 S43722 3313 26638 

Input File 2

 S13109 3738 31081 0 
 S13109 3737 31080 0 
 S00033 3008 29985 0 
 S00033 3007 29984 0 
 S00022 4130 31838 0 
 S00022 4129 31837 0 
 S00188 3317 27372 0 
 S45002 3759 31832 0 
 S45002 3758 31831 0 
 S45002 3757 31830 0 
 S43722 3020 26345 0 
 S43722 3019 26344 0 
 S00371 3737 33636 0 
 S00371 3736 33635 0 

Desired Output

 S00033 3008 29985 0 
 S00033 3007 29984 0
 S00022 4130 31838 0 
 S00022 4129 31837 0 
 S00188 3317 27372 0
 S00371 3737 33636 0 
 S00371 3736 33635 0 

Ответы [ 2 ]

6 голосов
/ 08 декабря 2010

awk 'FNR==NR{a[$1]++;next}!a[$1]' file1 file2

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

FNR==NR

Если у вас есть два (или более) входных файла для awk, NR вернется к 1 в первой строке следующего файла, тогда как FNR продолжит увеличиваться с того места, где оно было остановлено. Проверяя FNR==NR, мы в основном проверяем, анализируем ли мы в настоящее время первый файл.

a[$1]++

Если мы будем анализировать первый файл (см. Выше), то создадим ассоциативный массив с первым полем $1 в качестве ключа и затем увеличим значение на 1. Это, по сути, позволяет нам создать ' увиденный список.

next

Эта команда говорит awk не обрабатывать дальнейшие команды, читать следующую запись и начинать заново. Мы делаем это, потому что file1 предназначен только для установки ассоциативного массива

!a[$1]

Эта строка выполняется только тогда, когда FNR==NR имеет значение false, то есть мы не анализируем файл1 и, следовательно, должны анализировать файл2. Затем мы используем первое поле $1 файла file2 в качестве ключа для индексации в нашем «видимом» списке, созданном ранее. Если возвращаемое значение равно 0, это означает, что мы не видели его в file1, и поэтому мы должны напечатать эту строку. И наоборот, если значение не равно нулю, мы видели в файле1 и, следовательно, не выводим его значение. Обратите внимание, что !a[$1] эквивалентно !a[$1]{print}, потому что действие по умолчанию, если оно не задано, - это печать всей строки.

1 голос
/ 08 декабря 2010

Если вам не нужно сохранять порядок строк, вы можете использовать подстановку процессов в Bash, Korn или Z shell вместе с утилитами join и sort:

join -v 2 <(sort file_1) <(sort file_2)

Если вы используете оболочку без подстановки процессов, вам придется предварительно отсортировать файлы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...