Запретить "foo" сопоставлять "foo-bar" с помощью grep -w - PullRequest
0 голосов
/ 28 марта 2019

Я использую grep в своем скрипте Perl и пытаюсь найти точное ключевое слово, которое я даю. Проблема в том, что «-w» не распознает символ «-» в качестве разделителя.

Пример: Допустим, у меня есть эти две записи:

A1BG    0.0767377011073753
A1BG-AS1    0.233775553296782

если я дам grep -w "A1BG" он возвращает оба из них, но я хочу только точный.

Есть предложения? Большое спасибо заранее.

PS.

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

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

#Find the average fc between common genes
sub avg {
my $total;
$total += $_ foreach @_;
   return $total / @_;
}

my @mykeys = `cat G13_T.txt| awk '{print \$1}'| sort -u`;
foreach (@mykeys)
{
    my @TSS = ();

    my $op1 = 0;

    my $key = $_;
    chomp($key);
    #print "$key\n";
    my $command = "cat G13_T.txt|grep -E '([[:space:]]|^)$key([[:space:]]|\$)'";
    #my $command = "cat Unique_Genes/G13_T.txt|grep -w $key";
    my @belongs= `$command`;
    chomp(@belongs);
    my $count = scalar(@belongs);
    if ($count == 1) {
            print "$belongs[0]\n";
    }
    else {
            for (my $i = 0; $i < $count; $i++) {
                    my @token = split('\t', $belongs[$i]);
                    my $lfc = $token[1];
                    push (@TSS, $lfc);
            }
            $op1 = avg(@TSS);
            print $key ."\t". $op1. "\n";
    }
}

Ответы [ 2 ]

3 голосов
/ 28 марта 2019

Если я правильно получил разъяснения в комментариях, цель состоит в том, чтобы найти среднее значение (второй столбец) для уникальных имен в первом столбце. Тогда нет необходимости во внешних инструментах.

Читайте файл построчно и складывайте значения для каждого имени. Уникальность имени обеспечивается использованием хэша с именами, являющимися ключами. Наряду с этим также отслеживать их количество

use warnings;
use strict;
use feature 'say';

my $file = shift // die "Usage: $0 filename\n";

open my $fh, '<', $file or die "Can't open $file: $!";

my %results;

while (<$fh>) {
    #my ($name, $value) = split /\t/;
    my ($name, $value) = split /\s+/;  # used for easier testing

    $results{$name}{value} += $value;
    ++$results{$name}{count};
}

foreach my $name (sort keys %results) { 
    $results{$name}{value} /= $results{$name}{count} 
        if $results{$name}{count} > 1;

    say "$name => $results{$name}{value}";
}

После обработки файла каждое накопленное значение делится на его счет и перезаписывается на него, поэтому его среднее значение (/= делит и присваивает), если считать > 1 (в качестве небольшой меры эффективности).

Если есть какая-либо польза от знания всех значений, найденных для каждого имени, то сохраните их в arrayref для каждого ключа вместо добавления их

while (<$fh>) {
    #my ($name, $value) = split /\t/;
    my ($name, $value) = split /\s+/;  # used for easier testing

    push @{$results{$name}}, $value;
}

где теперь нам не нужен счетчик, так как он определяется количеством элементов в массиве (ref)

use List::Util qw(sum);

foreach my $name (sort keys %results) {
    say "$name => ", sum(@{$results{$name}}) / @{$results{$name}};
}

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

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

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

3 голосов
/ 28 марта 2019

Вы можете использовать регулярное выражение POSIX ERE с grep следующим образом:

grep -E '([[:space:]]|^)A1BG([[:space:]]|$)' file

Для возврата только совпадений (не совпадающих строк):

grep -Eo '([[:space:]]|^)A1BG([[:space:]]|$)' file

Детали

  • ([[:space:]]|^) - Группа 1: пробел или начало строки
  • A1BG - подстрока
  • ([[:space:]]|$) - Группа 2: пробел или конец строки
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...