@Yestestvenno
Системный администратор

Как сравнить 2 файла grep?

Есть 2 файла в одному милион записей в другом 500 милионов

оба файла одинаковой структуры но отличаются данными

Семь столбцов расделяемые комой $1,$2,$3,$4,$5,$6,$7
пример

хххххххх, хххххх,хххххх,хххххх,хххххх,ххххх,хх
хххххххх, хххххх,хххххх,хххххх,хххххх,ххххх,хх
хххххххх, хххххх,хххххх,хххххх,хххххх,ххххх,хх

нужно во втором файле найти строки (и вывести всю строку в файл) у которых совпадает $1 и $3 но другой $6
в первойм файле $6=q1 во втором $6=q1-q3
столбец $1 всегда начинается с 9

решение есть но выполнение скрипта = неделя
nano /tmp/comand
#отфильтровал файл 2 убрав значения $6=q1
grep -E "^9.*q2|^9.*q3" /tmp/file2.txt > /tmp/file22.txt
# Преобразование в исполняющий файл с поиском по 1 и 3 столбцу из исходного файла
cat /tmp/file22.txt | awk -F"," '{print "grep -E \"" $1 ".*" $3 ".*q2" "|" $1 ".*" $3 ".*q3" "\"" " /tmp/file1.txt >> /tmp/results.txt"}' > /tmp/comand
#очищення файла
cat /dev/null > /tmp/results.txt
сохраняем с именем /tmp/comand, делаем исполняемым chmod +x /tmp/comand, запускаем ./tmp/comand

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

P.S. если бы не нужно было вывыодить всю строку из файла 2 проблема думаю решилась бы с помощю
comm -2 file1 file2 > file3 но не факт :)
  • Вопрос задан
  • 2916 просмотров
Решения вопроса 4
saboteur_kiev
@saboteur_kiev Куратор тега Linux
software engineer
на Perl:
#/usr/bin/perl
open(FILE1,"a.txt");
open(FILE2,"b.txt");

foreach $line (<FILE1>) {
 chomp $line;
 ($a, $b, $c, $d, $e, $f, $g)=split(",",$line);
  $array{$a}{$c}=$f;
}

foreach $line (<FILE2>) {
 chomp $line;
 ($a, $b, $c, $d, $e, $f, $g)=split(",",$line);
  if ($array{$a}{$c}!=$f) {
    print "$line, [differs from: $array{$a}{$c}]\n";
  }
}


Укажите первым файлом тот, что поменьше.
Ответ написан
Комментировать
martin74ua
@martin74ua Куратор тега Linux
Linux administrator
первым проходом выделяем из второго файла все строки, в которых есть совпадения по первому столбцу, вторым проходом выделяем совпадения по третьему столбцу, третьим исключаем ненужное по 6-му столбцу.

если можно - примеры файлов по несколько сотен строк дайте мылом, попробую написать
Ответ написан
Adamos
@Adamos
Строки с несовпадающим $6 вы уже выкинули.
Перегоняем оба файла в формат $1,$3, отбрасывая прочую информацию и убирая дубли.
Сортируем, находим пересечение этих файлов.
Перегоняем второй в формат $1,$3,$2,$4,$5,$6,$7 и сортируем.
На своем любимом языке программирования открываем этот файл (1) и файл пересечений (2), сравнивая текущую строку в файле (2) с началом текущей строки в файле (1).
Если они совпадают - выводим, переставив столбцы.
Если нет - читаем следующую строку из файла, строка в котором оказалась меньше другого (данные-то отсортированы).
В один проход получаем результат, никаких недель.
Ответ написан
Комментировать
@Yestestvenno Автор вопроса
Системный администратор
Огромное спасибо за идеи по решению, решил осваивать perl =)
Сергей спасибо вам .... немного почитал переделал и вуаля готово)))

Adamos Руслан Федосеев и вам спасибо применил ваши советы для предварительной подготовки файла к запуску основного скрипта в других его вариациях (не представленно ниже)

Вот такое страшненькое написал, покритикуйте пожалуйста!
#!/usr/bin/perl
# Содержимое файла test1.pl
open(FILE0,"0.txt") || die "Файл 0 не найден!";
open(FILE1,"1.txt") || die "Файл 1 не найден!";
############# записываем файлы в масивы array0\array1 и читаем количество строк n\m
$n=0;
foreach $line0 () {
chomp $line0;
$n=$n+1;
$array0[$n]=$line0;
#print "$array0[$n]\n"
}
#print "$n\n";
$m=0;
foreach $line1 () {
chomp $line1;
$m=$m+1;
$array1[$m]=$line1;
#print "$array1[$m]\n"
}
#print "$m\n";
############# перебираем каждую строку масива array0 и сопоставляем ее с каждой строкой масива array1 если проходит условия if то дозаписываем значение $i масива array1 в $j масива array3
############# для каждого значения масива array0 выводим значения array0 + строки array1 (как масив array3) которые проходят условия
open (rFILE, '>r.txt');
for ($i = 1; $i <= $n; $i++) {
$array3[$i]="";
for ($j = 1; $j <= $m; $j++) {
($a0, $b0, $c0, $d0, $e0)=split(",",$array0[$i]);
($a1, $b1, $c1, $d1, $e1)=split(",",$array1[$j]);
if ($a0==$a1 && $c0==$c1 && $d0!=$d1) {
#print "$array0[$i],$array1[$j]\n";
#print "$a0, $a1\n";
$array3[$i]="$array3[$i], $array1[$j]"
}
}
print rFILE "$array0[$i] $array3[$i]\n";
print "$array0[$i] $array3[$i]\n";
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы