2010-01-29 3 views
3

Учитывая эти два файла:Finding Набор комплемента в 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' 
+1

Возможно, у вас есть все основания использовать однострочный интерфейс Unix, но подумали ли вы о написании сценария Perl или Python? Это может быть быстрее писать и читать и изменять. Python имеет встроенные функции на языке, поэтому в нескольких строках вы можете достичь того, что вы пытаетесь сделать здесь. – avpx

+2

@avpx: вы правы. В Python это так же просто, как «.» .join (set (open («A.txt ')) - set (open (' B.txt '))) '. –

+0

@Alok: Это очень хороший способ сделать это, конечно, короче того, что я написал. Престижность. – avpx

ответ

10
comm -2 -3 <(sort A.txt) <(sort B.txt) 

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

Edit: На самом деле, 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 
2

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

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

@ ghostdog74: Странно, почему это дает различный результат в моей машине: 3, 5, 1, 2, 4, – neversaint

+0

какую ОС вы используете? используйте nawk на Solaris. – ghostdog74

3

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

также обратите внимание, что comm не вычисляет истинное разность заданий; если линия повторяется в А, и повторяется меньшее количество раз в 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 
1

I wrote a program recently called Setdown что делает Набор операций с кли.

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

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

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

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

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

Смежные вопросы