Сравнить строки в файле, имеющем общий последний столбец, но отличающийся в другом столбце

Оказалось, что проблема была вызвана глупой строкой в .bashrc

TERM=xterm; export $TERM

поэтому после запуска screen в нем было TERM=xterm вместо TERM=screen. После удаления этой строки проблема исчезла.

0
06.09.2018, 22:58
2 ответа

Предполагая, что вкладка -разделена файлом, вы можете использовать GNU awk:

gawk -F'\t' 'NR == FNR {count[$6][$4]++; next} length(count[$6]) > 1' file file
chr10   102979  103832  HSF1        305
chr10   102979  103832  HIF1AN  1   305
chr10   102979  103832  HSF1        305
chr10   103124438   103124851   HSF1        471
chr10   103124438   103124851   EGLN1   2   471

Это проходит через файл дважды :первый раз, чтобы подсчитать, сколько значений $4 встречается для каждых $6; второй раз для вывода записи, если для этих $6 имеется более 1 значения $4.

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


Та же логика в perl

perl -Mautodie -e '
    open $f, "<", shift;
    while (<$f>) {
        @F = split /\t/;
        $c{ $F[5] }{ $F[3] }++;
    }
    # re-process the file
    seek $f, 0, 0;
    while (<$f>) {
        @F = split /\t/;
        print if scalar keys %{ $c{$F[5]} } > 1;
    }
' file
2
28.01.2020, 02:31

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

Обработка буфера означает попытку найти хотя бы одну пару последовательных строк, которые не разделяют значение 4-го столбца, и печать буфера в случае успеха.

Я сохранил точные строки в буфере вместе с отдельными столбцами для более удобного вывода и более легкого доступа к значениям.

#!/usr/bin/perl
use warnings;
use strict;

sub process {
    my (@rows) = @_;
    my $different;
    for my $i (1.. $#rows) {
        $different = 1, last if $rows[ $i - 1 ][4] ne $rows[$i][4];
    }
    print map "$_->[0]\n", @rows if $different;
}

my @buffer;
while (<>) {
    chomp;
    my @columns = split;
    if (! @buffer || $buffer[0][-1] == $columns[-1]) {
        push @buffer, [$_, @columns];
    } else {
        process(@buffer);
        @buffer = [$_, split];
    }
}
process(@buffer);
0
28.01.2020, 02:31

Теги

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