шелл, сравнить два файла (вывести только отличающие строки)

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

snikolaev
Сообщения: 195
ОС: Все подряд

шелл, сравнить два файла

Сообщение snikolaev »

Есть файл1 на 96к строк, файл2 на 87к строк (оба текст), нужно вывести только строчки из файла2, которых нет в файле1. Копаю в сторону diff --suppress-common-lines file2 file1, но он сумму мне выдает обоих файлов. Подскажите пожалуйста, как сформировать команду?
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: шелл, сравнить два файла

Сообщение eddy »

Посмотрите это, а если не подойдет, недавно кто-то уже задавал подобный вопрос про вывод разных строк в столбик.
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: шелл, сравнить два файла

Сообщение SLEDopit »

eddy писал(а):
27.04.2010 20:11
недавно кто-то уже задавал подобный вопрос про вывод разных строк в столбик.
Сравнение двух файлов столбиком
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
snikolaev
Сообщения: 195
ОС: Все подряд

Re: шелл, сравнить два файла

Сообщение snikolaev »

проверил примеры, там идет обьединение файлов и потом уже обработка, это я итак знаю как сделать. Мне надо получить именно строки файла2, которы нет в файле1. И именно командой консоли, скрипты и проги я и сам могу найти\написать. Дело принципа, так сказать ))
Я на пхп уже решил задакчу, единственный минус долго такие обьемы перегоняет.

Код: Выделить всё

<?php
$tofile = $argv[2];
$fromfile = file($argv[1]);
if(!isset($tofile)){ die("not set file to compare\r\n");}
if(!isset($fromfile)){ die("not set file from compare\r\n");}

foreach($fromfile as $url){
    $str = exec("cat ".$tofile." | grep ".$url."");
    if(($str == "")){
        exec
("echo ".trim($url)." >> ./tmp.txt");
        }
}
?>

может кому понадобится.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: шелл, сравнить два файла

Сообщение watashiwa_daredeska »

Код: Выделить всё

join -v2 <(sort -u файл1) <(sort -u файл2)
Если не нужны повторения и порядок следования строк не важен.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: шелл, сравнить два файла

Сообщение eddy »

snikolaev писал(а):
27.04.2010 20:36
проверил примеры, там идет обьединение файлов и потом уже обработка

Я вам дал ссылку на мою программку. Она файлы не объединяет. Только если будете использовать, обратите внимание на то, что оба файла целиком копируются в память, соответственно, размер оперативки и максимально допустимый размер для malloc'а должны быть достаточно большими (особенно если у вас файлы гигабайтные).
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
snikolaev
Сообщения: 195
ОС: Все подряд

Re: шелл, сравнить два файла

Сообщение snikolaev »

eddy, да, я видел, что это это программка, только вот мне нужна именно консольная команда.
ПыСы. Я думал сишные проги работают гораздо быстрее. Как-то прям очень медленно, как мой скрипт по времени
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: шелл, сравнить два файла

Сообщение eddy »

Хотите добавить скорости - оптимизируйте ;) Моя программка работает медленно, т.к. ищет при помощи strstr вхождение каждой строки целиком по всему второму файлу (правда, он расположен в памяти, поэтому немного процесс происходит быстрее).
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
snikolaev
Сообщения: 195
ОС: Все подряд

Re: шелл, сравнить два файла

Сообщение snikolaev »

watashiwa_darede... ваш вариант именно то, что надо. Спасибо.
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: шелл, сравнить два файла

Сообщение sash-kan »

watashiwa_daredeska писал(а):
27.04.2010 20:40

Код: Выделить всё

join -v2 <(sort -u файл1) <(sort -u файл2)
Если не нужны повторения и порядок следования строк не важен.
а comm разве не быстрей сработает? надо бы сравнить…
$ comm -1 -3 <(sort -u file1) <(sort -u file2)
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: шелл, сравнить два файла

Сообщение sash-kan »

upd. два файла взято, отличающихся одной строкой (это копии /usr/share/dict/american-english)

Shell

$ wc -l file* 98569 file1 98570 file2 197139 total $ time for i in $(seq 1 10); do join -v2 <(sort -u file1) <(sort -u file2) > /dev/null; done real 0m6.729s user 0m9.241s sys 0m0.156s $ time for i in $(seq 1 10); do comm -1 -3 <(sort -u file1) <(sort -u file2) > /dev/null; done real 0m5.089s user 0m7.744s sys 0m0.132s
таки comm чуть быстрее.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: шелл, сравнить два файла

Сообщение watashiwa_daredeska »

comm — GNUизм, я таким без сильной необходимости не пользуюсь.
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: шелл, сравнить два файла

Сообщение sash-kan »

watashiwa_darede... писал(а):
27.04.2010 22:21
comm — GNUизм
?
http://en.wikipedia.org/wiki/Comm
QUOTE писал(а):The comm command in Unix is a utility that is used to compare two files for common and distinct lines. comm is specified in the POSIX standard.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: шелл, сравнить два файла

Сообщение watashiwa_daredeska »

sash-kan писал(а):
27.04.2010 22:31
comm is specified in the POSIX standard.
Хм... А в man comm про CONFORMING TO ничего нет.

Shell

$ wc -l file* 1048576 file1 1048576 file2 2097152 total $ time for i in $(seq 5); do join -v1 <(sort -u file1) <(sort -u file2) >/dev/null; done real 0m32.457s user 0m58.064s sys 0m0.880s $ time for i in $(seq 5); do comm -1 -3 <(sort -u file1) <(sort -u file2) >/dev/null; done real 0m33.060s user 0m59.120s sys 0m0.948s
Пофиг. Даже чуть наоборот получилось. Непонятно, нафига этот comm вообще нужен, если есть join. Реально никогда не требовался вывод в 3 колонки, которые предлагает comm.
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: шелл, сравнить два файла

Сообщение sash-kan »

watashiwa_darede... писал(а):
27.04.2010 22:38
А в man comm

Код: Выделить всё

$ man -Pcat join | tail -n 1
GNU coreutils 6.9.92.4-f088d-dirtJanuary 2008                          JOIN(1)
$ man -Pcat comm | tail -n 1
GNU coreutils 6.9.92.4-f088d-dirtJanuary 2008                          COMM(1)


watashiwa_darede... писал(а):
27.04.2010 22:38
Непонятно, нафига этот comm вообще нужен, если есть join.
а-а-а, ну, это меняет дело! (улыбка)
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: шелл, сравнить два файла

Сообщение watashiwa_daredeska »

watashiwa_darede... писал(а):
27.04.2010 22:38
Хм... А в man comm про CONFORMING TO ничего нет.
Действительно, присутствует: http://www.opengroup.org/onlinepubs/009695...ities/comm.html
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: шелл, сравнить два файла

Сообщение sash-kan »

watashiwa_darede... писал(а):
27.04.2010 22:38
join -v1
watashiwa_darede... писал(а):
27.04.2010 22:38
comm -1 -3
это, кстати, разные команды. результаты у них разные.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: шелл, сравнить два файла

Сообщение watashiwa_daredeska »

sash-kan писал(а):
27.04.2010 22:46
это, кстати, разные команды. результаты у них разные.
Ну, пусть будет так:

Shell

$ wc -l file*; \ time for i in $(seq 5); do join -v2 <(sort -u file1) <(sort -u file2) >/dev/null; done; \ time for i in $(seq 5); do comm -1 -3 <(sort -u file1) <(sort -u file2) >/dev/null; done 1048576 file1 1048576 file2 2097152 total real 0m33.671s user 1m0.104s sys 0m0.848s real 0m32.955s user 0m58.916s sys 0m0.836s
Шило на мыло, в общем. Да и вообще, если посмотреть на real, то становится понятно, что меряем мы тут sort, а не join с comm'ом :) Чтобы их мерять, надо заранее отсортировать файлы.

Shell

$ sort -u file1 >file1s; sort -u file2 >file2s $ wc -l file*s; \ time for i in $(seq 5); do join -v2 file{1,2}s >/dev/null; done; \ time for i in $(seq 5); do comm -1 -3 file{1,2}s >/dev/null; done 1048575 file1s 1048576 file2s 2097151 total real 0m9.472s user 0m9.385s sys 0m0.088s real 0m9.411s user 0m9.333s sys 0m0.080s
Ну, где-то так.
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: шелл, сравнить два файла

Сообщение sash-kan »

доводим до апефеоза (улыбка). сравниваем один и тот же файл:

Shell

$ time for i in $(seq 1 10); do join -v2 file1 file1 > /dev/null; done real 0m1.862s user 0m1.704s sys 0m0.020s 4 time for i in $(seq 1 10); do comm -1 -3 file1 file1 > /dev/null; done real 0m0.214s user 0m0.176s sys 0m0.020s
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: шелл, сравнить два файла

Сообщение sash-kan »

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

Shell

$ for i in $(seq 1 10); do cat /usr/share/dict/american-english; done | sort > file1 $ cp file1 file2 $ echo zzz >> file2 $ wc -l file* 985690 file1 985691 file2 1971381 total $ join -v2 file1 file2 zzz $ comm -1 -3 file1 file2 zzz $ time for i in $(seq 1 5); do join -v2 file1 file2 > /dev/null; done real 0m3.429s user 0m3.312s sys 0m0.048s $ time for i in $(seq 1 5); do comm -1 -3 file1 file2 > /dev/null; done real 0m0.905s user 0m0.776s sys 0m0.072s
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
Ленивая Бестолочь
Бывший модератор
Сообщения: 2760
ОС: Debian; gentoo

Re: шелл, сравнить два файла

Сообщение Ленивая Бестолочь »

а диф быстрее или медленнее?
типа так, как-нибудь:
diff <(sort -u file1) <(sort -u file2)
Солнце садилось в море, а люди с неоконченным высшим образованием выбегали оттуда, думая, что море закипит.
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: шелл, сравнить два файла

Сообщение SLEDopit »

Ленивая Бестолочь писал(а):
28.04.2010 23:56
а диф быстрее или медленнее?
типа так, как-нибудь:
diff <(sort -u file1) <(sort -u file2)
диф сильно дольше:

Код: Выделить всё

 $ wc -l file*
   990000 file1
   990001 file2
  1980001 total
 $ time for i in $(seq 1 5); do join -v2 file1 file2 > /dev/null; done

real    0m9.965s
user    0m8.357s
sys    0m1.376s
 $ time for i in $(seq 1 5); do comm -1 -3 file1 file2 > /dev/null; done

real    0m3.474s
user    0m2.872s
sys    0m0.488s
 $ time for i in $(seq 1 5); do diff <(sort -u file1) <(sort -u file2) > /dev/null; done

real    0m24.376s
user    0m41.331s
sys    0m2.292s
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: шелл, сравнить два файла

Сообщение drBatty »

Ленивая Бестолоч... писал(а):
28.04.2010 23:56
а диф быстрее или медленнее?

диф значительно лучше и удобнее. а следовательно - дольше...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали: