LINUX.ORG.RU

Проверить файлы на совпадение

 


0

2

Есть 4 файла, каждый из которых содержит множество строк вида

2015-02-26_16:27:54 NO
Где первый столбец - это время, а во втором столбце либо YES, либо NO. Файлы содержат одинаковое количество строк и n-ная строка всех файлов содержит одно и то же время (отличаться могут только YES/NO). Подскажите, пожалуйста, как реализовать следующее: надо вывести количество совпадающих строк в двух заданных файлах. Т.е, если, например, 2, 3, 5, 20, 21 строки в двух указанных файлах имеют одинаковый второй столбец (YES/NO), их надо будет посчитать (время у строк с одним и тем же номером одинаковое в любом случае). Заранее спасибо

★★

Способов масса. Например:

$ D=$(diff "$file1" "$file2" | wc -l);A=$(cat "$file2" | wc -l); eval "$A-$D"
В синтаксисе где-то мог ошибиться, но принцип, думаю, ясен.

Kroz ★★★★★ ()
Последнее исправление: Kroz (всего исправлений: 3)
Ответ на: комментарий от Kroz

diff работает не совсем так, как нужно: в случае, когда в каждом из файлов N совпадающих строк, он выводит удвоенное число строк:

< 2015-02-26_16:27:54 NO
< 2015-02-26_16:28:55 NO
< 2015-02-26_16:29:55 NO
< 2015-02-26_16:30:56 NO
< 2015-02-26_16:31:56 NO
< 2015-02-26_16:32:57 NO
< 2015-02-26_16:33:58 NO
< 2015-02-26_16:34:58 NO
< 2015-02-26_16:35:59 NO
< 2015-02-26_16:37:00 NO
---
> 2015-02-26_16:27:54 YES
> 2015-02-26_16:28:55 YES
> 2015-02-26_16:29:55 YES
> 2015-02-26_16:30:56 YES
> 2015-02-26_16:31:56 YES
> 2015-02-26_16:32:57 YES
> 2015-02-26_16:33:58 YES
> 2015-02-26_16:34:58 YES
> 2015-02-26_16:35:59 YES
> 2015-02-26_16:37:00 YES
В принципе, можно делить на два, но мне бы нужно максимально точное значение, а вот эти пустые строки, обозначающие у diffа пропуск, могут испортить картину.

Valdor ★★ ()
Ответ на: комментарий от anonymous

Спасибо! Работает как надо. А что изменится с увеличением размера? Не думаю, что файлы превысят у меня 10 метров каждый, но мало ли. Оперативной памяти достаточно.

Valdor ★★ ()
declare -i counter=0
while IFS= read -r line1; do
    IFS= read -r line2 <&3
    [[ "${line1##* }" != "${line2##* }" ]] && (( ++counter ))
done < file1 3< file2
echo $counter
anonymous ()
#!/bin/bash

function gen() {
  seq 50 | while read i; do
    echo $i $(($RANDOM%2))
  done
}

gen > file1.txt
gen > file2.txt

awk '{
  getline line<"file2.txt"
  k+=$0==line
}
END{
  print k
}' file1.txt
anonymous ()
Ответ на: комментарий от Valdor

ну и OK тогда! а то я уж думал MIPS какой-нибудь дохлый :)

anonymous ()
$ join file1 file2 | awk '$2 == $3 { i++ } END { print i }'
unterwulf ()
Ответ на: комментарий от anonymous

О, спасибо, узнал о существовании declare в bash.

hobbit ★★★★★ ()

Вообще-то, в coreutils специально для этого есть удостоенная одобрения POSIX утилитка:

  comm -1 -2 file1 file2 | wc -l

ABW ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.