Поиск дополнения к набору в Unix

Учитывая это два файла:

 $ cat A.txt     $ cat B.txt
    3           11
    5           1
    1           12
    2           3
    4           2

Я хочу найти номер строки, который находится в "НО НЕ" в B. Какая команда unix для него?

Я попробовал это, но, похоже, не удалось:

comm -3 <(sort -n A.txt) <(sort -n B.txt) | sed 's/\t//g' 

5 ответов

Решение
comm -2 -3 <(sort A.txt) <(sort B.txt)

надо делать что хочешь, если я тебя правильно понял.

Редактировать: На самом деле, comm файлы должны быть отсортированы в лексикографическом порядке, так что вы не хотите -n в вашем sort команда:

$ cat A.txt
1
4
112
$ cat B.txt
1
112
# Bad:
$ comm -2 -3 <(sort -n B.txt) <(sort -n B.txt)
4
comm: file 1 is not in sorted order
112
# OK:
$ comm -2 -3 <(sort A.txt) <(sort B.txt)
4

Ты можешь попробовать это

$ awk 'FNR==NR{a[$0];next} (!($0 in a))' B.txt A.txt
5
4

Обратите внимание, что решение awk работает, но сохраняет дубликаты в A (которых нет в B); решение python дублирует результат

также обратите внимание, что comm не вычисляет истинную разность множеств; если линия повторяется в A, и повторяется в B меньше, comm оставит "лишнюю" строку (и) в результате:

$ cat A.txt 
120
121
122
122
$ cat B.txt 
121
122
121
$ comm -23 <(sort A.txt) <(sort B.txt)
120
122

если это поведение нежелательно, используйте sort -u удалить дубликаты (только дубли в вопросе А):

$ comm -23 <(sort -u A.txt) <(sort B.txt)
120

Недавно я написал программу под названием Setdown, которая выполняет операции Set из клима.

Он может выполнять операции над множествами, написав определение, подобное тому, что вы написали бы в Makefile:

someUnion: "file-1.txt" \/ "file-2.txt"
someIntersection: "file-1.txt" /\ "file-2.txt"
someDifference: someUnion - someIntersection

Это довольно круто, и вы должны это проверить. Лично я не рекомендую использовать специальные команды, которые не были созданы для выполнения заданий. Он не будет работать хорошо, когда вам действительно нужно выполнить много операций над множествами или если у вас есть какие-либо операции над множествами, которые зависят друг от друга. Кроме того, setdown позволяет вам писать операции над множествами, которые зависят от других операций над множествами!

Во всяком случае, я думаю, что это довольно круто, и вы должны полностью проверить это.

Примечание: я думаю, что Setdown намного лучше, чем comm просто потому, что Setdown не требует правильной сортировки входных данных. Вместо этого Setdown отсортирует ваши входные данные и использует внешнюю сортировку. Так что он может обрабатывать большие файлы. Я считаю это большим преимуществом, потому что количество раз, которое я забыл сортировать файлы, которые я передал в comm, неисчислимо.

Вот еще один способ сделать это:

      join -v1 <(sort A.txt) <(sort B.txt)

Из документации по join:

'-v номер-файла' Вывести по строке для каждой нежелательной строки в файле номер-файла ('1' или '2') вместо обычного вывода.

Другие вопросы по тегам