Вложенные 'awk' в, 'в то время как' цикл, проанализируйте два файла линию за линией и сравните значения столбцов

1-я Кв. - получает заголовки Linux установки - $ (uname-r)

2-я способность переустанавливает nvidia-kernel-dkms

3-я перезагрузка

4
23.03.2015, 16:20
2 ответа

Первая проблема заключается в том, что вы не можете использовать bash-переменные внутри awk вот так. $a внутри awk вычисляется в поле a, но a пустая, так как она определена не в awk, а в bash. Один из способов обойти это - использовать опцию awk -v для определения переменной

-v var=val
--assign var=val
   Assign the value val to the variable var,  before  execution  of
   the  program  begins.  Such variable values are available to the
   BEGIN rule of an AWK program.

Таким образом, вы можете сделать:

while read chr a b cov; do 
  awk -v a="$a" -v b="$b" '($2<=a && b <= $3) {print NR}' exons.bed > out$a$b 
done < reads.bed

У вас там еще одна ошибка. Для того, чтобы считывание попало в экзон, начальная позиция считывания должна быть больше начальной позиции экзона, а его конечная позиция меньше конечной позиции экзона. Вы используете $2<=a &&b <= $3, который выберет чтение, чье начало находится за пределами экзона. Вам нужно $2>=a && $3<=b.

В любом случае, запуск такого типа вещей в бэш-цикле очень неэффективен, так как ему нужно прочитать входной файл один раз для каждой пары a и b. Почему бы не сделать все это в awk?

awk 'NR==FNR{a[NR]=$2;b[NR]=$3; next} {
        for (i in a){
           if($2>=a[i] && $3<=b[i]){
            out[i]=out[i]" "FNR 
        }}}
        END{for (i in out){
                   print "Exon",i,"contains reads of line(s)"out[i],\
                   "of reads file" 
        }}' exons.bed reads.bed

Скрипт, приведенный выше, выдает следующий результат, если запустить его на ваших примерах файлов:

Exon 1 contains reads of line(s) 1 of reads file
Exon 2 contains reads of line(s) 2 3 4 5 of reads file

Вот то же самое в менее сжатом виде для ясности

#!/usr/bin/awk -f

## While we're reading the 1st file, exons.bed
NR==FNR{
    ## Save the start position in array a and the end 
    ## in array b. The keys of the arrays are the line numbers.
    a[NR]=$2;
    b[NR]=$3; 
    ## Move to the next line, without continuing
    ## the script.
    next;
}
 ## Once we move on to the 2nd file, reads.bed
 {
     ## For each set of start and end positions
     for (i in a){
         ## If the current line's 2nd field is greater than
         ## this start position and smaller than this end position,
         ## add this line number (FNR is the current file's line number)
         ## to the list of reads for the current value of i. 
         if($2>=a[i] && $3<=b[i]){
             out[i]=out[i]" "FNR 
         }
     }
 }
 ## After both files have been processed
 END{
     ## For each exon in the out array
     for (i in out){
         ## Print the exon name and the redas it contains
         print "Exon",i,"contains reads of line(s)"out[i],
             "of reads file" 
        }
3
27.01.2020, 20:54

я подозреваю, что это не имеет ничего общего с вашей установкой mc - полагаю, это сообщение будет отображаться для любой программы, которую вы хотите установить через apt . что бы вы ни делали , не следуйте его совету и запустите autremove.

если вы хотите, чтобы все перечисленные пакеты были установлены, то скопируйте список, который apt говорит, что он хочет удалить, и скажите apt , чтобы установить эти пакеты:

$ sudo apt-get install aptdaemon cheese-common empathy-common etc

сделайте несколько пакетов за раз и посмотрите, если список рекомендаций становится меньше каждый раз - он должен.

-121--196945-

Попробуйте

parent_path=$(echo "$current_path"/ | sed -e "s|[^/]||g" -e "s|/|../|g")
cd "${current_path}" ; ln -s "${parent_path}${parent_file_to_link}"

Это выполняется просто путем подсчета косых черт в «$ {current _ path}» . Требуемая глубина на единицу больше числа косых черт (например, глубина test/dir/hello , которая содержит две косые черты, равна 3), поэтому мы просто добавим косую черту: echo «$ current _ path »/. Вставьте его в раздел . Поскольку мы манипулируем косыми чертами, проще использовать символ, отличный от / в качестве разделителя для команды sed "s s ; Мне нравится использовать вертикальную полосу ( | ). s | [^/] | | g находит все символы, которые не являются косыми чертами и заменяет их ничем. Другими словами, он удаляет все символы, кроме косой черты. Так, для значения «$ {current _ path}» test/dir/hello , мы echo "d test/dir/hello/ и затем разрезали его на ///. Затем s |/| ../| g " меняет каждую / на ../, так что мы получаем ../../../.

Примечание: это предполагает, что «$ {current _ path}» не имеет в ней лишних (ненужных) косых черт. Например, test/dir//hello и test/dir/hello/ логически эквивалентны test/dir/hello , но они содержат вводящее в заблуждение количество косых знаков, который приведет к повреждению этого процесса.

P.S. Всегда цитировать все переменные оболочки, если нет причины не и ты уверен, что знаешь, что делаешь. Использование фигурных скобок (как в $ { переменная _ name } ) не эквивалентна кавычкам.

-121--186034-

Я знаю, что это не совсем то, за чем вы следите, но лично - я не ладлю с неловко и поэтому предложил бы пойти в порядке.

Что-то вроде этого:

#!/usr/bin/perl

#REALLY GOOD IDEA at the start of any perl code
use strict;
use warnings;

#open some files for input
open( my $exons, "<", 'exons.bed' ) or die $!;

#record where our exons start and finish. 
my %start_of;
my %end_of;

#read line by line our exons file. 
#extract the 3 fields and save 'start' and 'end' in a hash table. 
while (<$exons>) {
    my ( $something, $start, $end ) = split;

    my $exon_id = $.;    #line number;
    $start_of{$exon_id} = $start;
    $end_of{$exon_id}   = $end;
}
close ( $exons );

my %exons;
#run through 'reads' line by line, extracting the files. 

open( my $reads, "<", 'reads.bed' ) or die $!;
while (<$reads>) {
    my ( $thing, $read_start, $read_end, $value ) = split;

    #cycle through each exon. 
    foreach my $exon_id ( keys %start_of ) {

        #check if _this_ 'read' is within the start and end ranges. 
        if (    $read_start >= $start_of{$exon_id}
            and $read_end <= $end_of{$exon_id} )
        {
            #store the line number in our hash %exons. 
            push( @{ $exons{$exon_id} }, $. );
        }
    }
}
close ( $reads ); 

#cycle through %exons - in 'id' order. 
foreach my $exon_id ( sort keys %exons ) {
    #print any matches. 
    print "exon ",$exon_id, " (", $start_of{$exon_id}, " - ", $end_of{$exon_id},
        ") contains reads of line:", join( ",", @{ $exons{$exon_id} } ), "\n";
}

Что дает ваш образец данных:

exon 1 (60005 - 60100) contains reads of line:1
exon 2 (61007 - 61130) contains reads of line:2,3,4,5

Вы должны иметь возможность расширить это, чтобы сделать некоторые более сложные проверки диапазона/валидации тривиально тоже!

2
27.01.2020, 20:54

Теги

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