Найдите строки из одного файла, которые не отображаются (даже частично) в другом файле

#shell #search #match

Вопрос:

Мне нужна команда оболочки Unix, чтобы найти строки из файла 1, которые вообще не отображаются в файле 2. Например —

файл1:

 aaa  bbb  

файл2:

 aaaccc  bb  

Ожидаемый результат:

 bbb  

(«aaa» из файла 1 появляется в файле 2 как часть более крупной строки «aaaccc»).

Я не могу использовать «связь», так как она работает только на полных строках. В этом случае я также хочу исключить строки в файле 2, которые содержат строки в файле 1 как часть больших строк, как описано выше.

Примечание.Я бы предпочел быстрый способ, если он существует, так как мои файлы ОЧЕНЬ большие.

Комментарии:

1. grep -f file2 file1 работает для этих образцов. Если этого недостаточно, пожалуйста, опубликуйте более исчерпывающие образцы, пожалуйста.

2. @JamesBrown grep занимает целую вечность для больших файлов. Есть ли самый быстрый способ?

3. Насколько велики ваши файлы? Помещаются ли они в память вашего (компьютера :D)?

4. @JamesBrown, конечно 🙂 каждая из них составляет около 400 тысяч строк

Ответ №1:

Один в awk, mawk, вероятно, самый быстрый, так что используйте его:

 $ awk ' NR==FNR { # process file1  a[$0] # hash all records to memory  next # process next record } { # process file2  for(i in a) # for each file1 entry in memory  if($0 ~ i) # see if it is found in current file2 record  delete a[i] # and delete if found } END { # in the end  for(i in a) # all left from file1  print i # are outputted }' file1 file2 # mind the order  

Выход:

 bbb  

Комментарии:

1. Спасибо за подробный ответ! Однако это не работает для меня 🙁 В прошлом я использовал только простые однострочные команды awk (например, печать и т. Д.), И они работали. Ваш ответ содержит символы новой строки, поэтому он не распознается моей оболочкой.

2. При попытке свернуть его в одну строку появляется надпись «синтаксическая ошибка».

3. Однострочный c’n’p’d из моей оболочки, он же оригинал : awk 'NR==FNR{a[$0];next}{for(i in a)if($0 ~ i)delete a[i]}END{for(i in a)print i}' file1 file2

4. Это сработало. Большое вам спасибо!!