bash: разница между join и comm - PullRequest
1 голос
/ 29 августа 2011
# comm -12 /tmp/src /tmp/txt | wc -l
  10338
# join /tmp/src /tmp/txt | wc -l
  10355

Оба файла представляют собой отдельные столбцы буквенно-цифровых строк и sort -ed.Разве они не должны быть одинаковыми?


Обновлено после @ Kevin-s ответа ниже:

cat /tmp/txt | sed 's/^[:space:]*//' > /tmp/stxt
cat /tmp/src | sed 's/^[:space:]*//' > /tmp/ssrc

и результат:

#join /tmp/ssrc /tmp/stxt | wc -l
516
# comm -12 /tmp/ssrc /tmp/stxt | wc -l
513

В ручнуюпроверка diff -s ... результаты отличаются из-за некоторых пробелов, которые не были удалены sed.

Ответы [ 4 ]

4 голосов
/ 29 августа 2011

Существует несколько различий между comm и join:

  1. comm сравнивает целые строки; join сравнивает поля в строках.
  2. comm печатает целые строки; join может печатать выбранные части линий.

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

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

src           txt
123           123
              123
              123

Если вы сделаете comm -12 src txt, вы получите одну строку вывода; если вы сделаете join src txt, вы получите три строки вывода. Это ожидается.

Команда join также может обрабатывать «внешние соединения», когда во втором файле отсутствуют данные для строки в первом файле (LEFT OUTER JOIN в терминах SQL) или наоборот (RIGHT OUTER JOIN), или оба сразу (ПОЛНОЕ НАРУЖНОЕ СОЕДИНЕНИЕ).

В целом, join - более сложная команда, но она пытается выполнить более сложную работу. Оба полезны; но они полезны в разных местах.

2 голосов
/ 29 августа 2011

Основная утилита join заключается в выборе строк, которые разделяют одно поле, как вы можете сделать в базе данных.Допустим, у вас есть следующие файлы:

File A
Alice  24
Bill   16
Claire 31
John   10
John  -14

File B
Bill   Copenhagen
John   Adelaide

... вы можете выбрать строки «Джон» и «Билл» из файла А, указав в качестве файла для присоединения файл Б и первое полекак поле для присоединения.Требование, чтобы оба файла были отсортированы в этом поле , на практике довольно громоздко.

1 голос
/ 30 августа 2011

Используйте [[:space:]] (вместо [:space:]) для удаления пробелов с помощью sed.

# compare
{
echo '   abc' | sed 's/^[:space:]*//'
echo '   abc' | sed 's/^[[:space:]]*//'
}
0 голосов
/ 29 августа 2011

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

$ echo -e '1\n2\n3\n5' > a
$ echo -e '1\n2\n4\n5' > b
$ comm a b
                1
                2
3
        4
                5
$ join a b
1
2
5
$

Edit: Join сравнивает только первое разделенное пробелами поле, но comm сравнивает всю строку.Поэтому любые пробелы в строке будут отличать выходные данные.

...