Извлечь подпоследовательность, соответствующую n:th шаблону из файла

find. -type f -exec md5sum {} +
7
28.11.2019, 10:01
7 ответов

Учитывая, что мы можем извлечь начальный индекс вместе с антикодоном:

len=7
prior=2

while IFS= read  -r line; do
    if [[ $line =~ Anticodon:" "([[:alpha:]]+)" at "([0-9]+) ]]; then
        anticodon=${BASH_REMATCH[1]}
        start=$(( BASH_REMATCH[2] - 1))  # string indexing is zero-based
    elif [[ $line == "Seq: "* ]]; then
        seq=${line#Seq: }
        printf "Seq: %s, Anticodon: %s\n" "${seq:start-prior:len}" "$anticodon"
    fi
done < file

Более сложное решение, которое каждый раз анализирует строку "Str :", но не жестко кодирует длину как 7 (жестко кодирует "n-й" шаблон):

8thSeq() {
    local seq=$1 str=$2
    local last=${str:0:1}
    local nth=8 n=1 start

    for (( i=1; i < ${#str}; i++)); do
        if [[ "${str:i:1}" != "$last" ]]; then
            ((n++))
            if ((n == nth)); then
                start=$i
            elif ((n == nth+1)); then
                echo "${seq:start:i-start}"
                break
            fi
        fi
        last=${str:i:1}
    done
}

while IFS= read  -r line; do
    if [[ $line =~ Anticodon:" "([[:alpha:]]+) ]]; then
        anticodon=${BASH_REMATCH[1]}
    elif [[ $line == "Seq: "* ]]; then
        seq=${line#Seq: }
    elif [[ $line == "Str: "* ]]; then
        str=${line#Str: }
        printf "Seq: %s, Anticodon: %s\n" "$(8thSeq "$seq" "$str")" "$anticodon"
    fi
done < file

Используя «больше» данных, оба решения выводят результат

Seq: CTCACAC, Anticodon: CAC
Seq: CTGAAGA, Anticodon: GAA
Seq: CTGCCAC, Anticodon: GCC
Seq: TTTACAC, Anticodon: TAC
Seq: CTGATAA, Anticodon: GAT
Seq: CTGATAA, Anticodon: GAT
Seq: CTGATAA, Anticodon: GAT
Seq: CTTCAAA, Anticodon: TCA
3
27.01.2020, 20:16

короткий пример, если я правильно понял вопрос.

если FILE.txt содержит предоставленные вами данные, вывод ниже строки для выполнения:

for I in $ (cat FILE.txt|egrep '^Seq :\s|^Str :\s'|sed ' :a;N;$!ba;s/Seq :\s *//g;s/\nStr :\s */|/g;' ); do B=$ (echo "$I"|вырезать -d'|' -f1 ); A=$ (echo "$I"|cut -d'|' -f2 ); [ ${ #A} ] && s=${A :0 :1} && s1=0 && s2=1 && n=1 && i=1 && while [ $i -lt $ { #А} ] ; do [ "${A :$i :1}" = "$s" ] && s2=$ (($s2+1 ))|| { n=$ (($n+1 )); если [ $n -lt 9 ]; тогда s=${A :$i :1}; с1=$i; с2=1; еще echo "${B :$s1 :$s2}"; я=${#А}; фи; }; i=$ (($i+1 )); Готово ; сделано

КТГССАС

ТТТАКАК

СТГАТАА

СТГАТАА

СТГАТАА

-1
27.01.2020, 20:16

Использованиеawk:

$ awk -f script.awk file
Sequence: CTCACAC, Anticodon: CAC, Type: Val
Sequence: CTGAAGA, Anticodon: GAA, Type: Phe
Sequence: CTGCCAC, Anticodon: GCC, Type: Gly
Sequence: TTTACAC, Anticodon: TAC, Type: Val
Sequence: CTGATAA, Anticodon: GAT, Type: Ile
Sequence: CTGATAA, Anticodon: GAT, Type: Ile
Sequence: CTGATAA, Anticodon: GAT, Type: Ile
Sequence: CTTCAAA, Anticodon: TCA, Type: SeC

Где script.awkследующая программа awk:

/^Type:/ {
        type = $2
        anticodon = $4
        split($6, pos, "-")
}

/^Seq:/ {
        seq = substr($2, pos[1]-2, length(anticodon) + 4)
        # or: seq = substr($2, pos[1]-2, pos[2]-pos[1]+5)
        printf "Sequence: %s, Anticodon: %s, Type: %s\n", seq, anticodon, type
}

Первый блок запускается любой строкой, начинающейся со строки Type:, и он выбирает тип и последовательность антикодонов из 2-го и 4-го полей, разделенных пробелами -, и разбивает 6-е такое поле на -для получения начальные и конечные координаты в последовательности.

Второй блок запускается строкой, начинающейся со строки Seq:, и выбирает последовательность из 2-го поля, разделенного пробелом -, используя начальную позицию антикодона и длину антикодона, считанную из последнего Type:. ] линии, убедившись, что с каждой стороны есть пара пар оснований -.

Затем производится вывод.


Следующий сценарий sedиспользует 8-й «шаблон» из строки Str:для извлечения нужной последовательности, а не числовые позиции для антикодона, указанные в строке Type:.

/^Type:[[:blank:]]*/ {
        s/.*Type: \([^[:blank:]]*\)[[:blank:]]*Anticodon: \([^[:blank:]]*\).*/ Anticodon: \2, Type: \1/
        h
}

/^Seq:[[:blank:]]*/ {
        s//Sequence: /
        G
        y/\n/,/
        w data.tmp
}

/^Str:[[:blank:]]*/ {
        s///
        s,\(\(\([<>.]\)\3*\)\{7\}\)\(\([<>.]\)\5*\).*,s/: \1\\(\4\\)[^\,]*/: \\1/;n,
        y/<>/../
        w pass2.sed
}

d

(замыкающий dне опечатка ).

Он делает это за два прохода.

При первом проходе создаются два новых файла, data.tmpи pass2.sed.

$ sed -f script.sed file

(здесь нет клеммного выхода)

Для заданных данных data.tmpбудет выглядеть как

Sequence: GTTTCCGTAGTGTAGCGGTtATCACATTCGCCTCACACGCGAAAGGtCCCCGGTTCGATCCCGGGCGGAAACA, Anticodon: CAC, Type: Val
Sequence: GCCGAAATAGCTCAGTTGGGAGAGCGTTAGACTGAAGATCTAAAGGtCCCTGGTTCGATCCCGGGTTTCGGCA, Anticodon: GAA, Type: Phe
Sequence: GCATGGGTGGTTCAGTGGTAGAATTCTCGCCTGCCACGCGGGAGGCCCGGGTTCGATTCCCGGCCCATGCA, Anticodon: GCC, Type: Gly
Sequence: GGTTCCATAGTGTAGTGGTtATCACGTCTGCTTTACACGCAGAAGGtCCTGGGTTCGAGCCCCAGTGGAACCA, Anticodon: TAC, Type: Val
Sequence: GGCCGGTTAGCTCAGTTGGTaAGAGCGTGGTGCTGATAACACCAAGGtCGCGGGCTCGACTCCCGCACCGGCCA, Anticodon: GAT, Type: Ile
Sequence: GGCCGGTTAGCTCAGTTGGTaAGAGCGTGGTGCTGATAACACCAAGGtCGCGGGCTCGACTCCCGCACCGGCCA, Anticodon: GAT, Type: Ile
Sequence: GGCCGGTTAGCTCAGTTGGTaAGAGCGTGGTGCTGATAACACCAAGGtCGCGGGCTCGACTCCCGCACCGGCCA, Anticodon: GAT, Type: Ile
Sequence: GCCCGGATGATCCTCAGTGGTCTGGGGTGCAGGCTTCAAACCTGTAGCTGTCTAGCGACAGAGTGGTTCAATTCCACCTTTCGGGCG, Anticodon: TCA, Type: SeC

, а pass2.sed— это скрипт sed, который пост -обрабатывает это:

s/:...............................\(.......\)[^,]*/: \1/;n
s/:...............................\(.......\)[^,]*/: \1/;n
s/:..............................\(.......\)[^,]*/: \1/;n
s/:...............................\(.......\)[^,]*/: \1/;n
s/:................................\(.......\)[^,]*/: \1/;n
s/:................................\(.......\)[^,]*/: \1/;n
s/:................................\(.......\)[^,]*/: \1/;n
s/:.................................\(.......\)[^,]*/: \1/;n

Применение pass2.sedк data.sedдает окончательный результат:

$ sed -f pass2.sed data.tmp
Sequence: CTCACAC, Anticodon: CAC, Type: Val
Sequence: CTGAAGA, Anticodon: GAA, Type: Phe
Sequence: CTGCCAC, Anticodon: GCC, Type: Gly
Sequence: TTTACAC, Anticodon: TAC, Type: Val
Sequence: CTGATAA, Anticodon: GAT, Type: Ile
Sequence: CTGATAA, Anticodon: GAT, Type: Ile
Sequence: CTGATAA, Anticodon: GAT, Type: Ile
Sequence: CTTCAAA, Anticodon: TCA, Type: SeC

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

5
27.01.2020, 20:16

Предположим, что вам нужно проанализировать повторения строки Str:

начало и конец

Поскольку последовательность шаблонов может меняться для каждого блока, нам нужен способ найти восьмой шаблон.

Можно извлечь каждый повторяющийся «шаблон» (из вашего описания все, что начинается с символа и заканчивается тем же символом)из строки с помощью (GNU )grep:

$ str='>>>>>>>..>>>>.......<<<<.>>>>>.......<<<<<....>>>>>.......<<<<<<<<<<<<.'

$ grep -Eo '(.)\1+' <<<"$str"
>>>>>>>
..
>>>>
.......
<<<<
>>>>>
.......
<<<<<
....
>>>>>
.......
<<<<<<<<<<<<

Итак, начало и длина шаблона 8(с использованием оболочки )равны:

pattern=8
splitstr=( $(grep -Eo '(.)\1+' <<<"$str") )
for((i=1;i<=pattern-2;i++)); do
    start=$((start+${#splistr[i]}))
done
len=${splitstr[pattern-1]}

Для любого шаблона (, который имеет 8 или более повторений ).

Или, короче, начало и конец:

start=$(echo "$str" | grep -Eo '^((.)\2+|.){7}'); start=${#start}
  end=$(echo "$str" | grep -Eo '^((.)\2+|.){8}');   end=${#end}

блоки

В AWK :возможно (и просто )разбить файл на блоки (строк, разделенных пустой строкой ), установив RSна пустое "".

поля

Если RSравно "", каждый блок далее автоматически делится на поля с помощью awk. Будучи последним полем($NFна языке awk ), строка содержит повторяющиеся символы.

Итак, в awk:

$ awk -vRS="" '{str=$NF; pat=8
cmd1="echo \"" str "\" | grep -Eo '\''^((.)\\2+|.){" pat-1 "}'\''";
cmd2="echo \"" str "\" | grep -Eo '\''^((.)\\2+|.){" pat   "}'\''";
cmd1 | getline start ; close(cmd1) ; start=length(start)
cmd2 | getline end   ; close(cmd2) ;   end=length(end)
print "Start:",start,"End:",end,"Sequence:",substr($(NF-2),start,end-start),"Anticodon:",$9,"Type:",$7
}' biopattern.txt


Start: 30 End: 37 Sequence: CCTCCCA Anticodon: CCC Type: Gly
Start: 31 End: 38 Sequence: CCTCACA Anticodon: CAC Type: Val
Start: 31 End: 38 Sequence: ACTGAAG Anticodon: GAA Type: Phe
Start: 30 End: 37 Sequence: CCTGCCA Anticodon: GCC Type: Gly
Start: 31 End: 38 Sequence: CTTTACA Anticodon: TAC Type: Val
Start: 32 End: 39 Sequence: GCTGATA Anticodon: GAT Type: Ile
Start: 32 End: 39 Sequence: GCTGATA Anticodon: GAT Type: Ile
Start: 32 End: 39 Sequence: GCTGATA Anticodon: GAT Type: Ile
Start: 33 End: 40 Sequence: GCTTCAA Anticodon: TCA Type: SeC

Что не совпадает с результатами других ответов, основанных на числе после at.

Может быть :Вы это имели в виду?

2
27.01.2020, 20:16

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

<data sed -E '
/^Type:|^Seq:|^Str:/ ! d
/^Type:/ {
   s/.*(Anticodon: [CGAT]*).*/\1/
   p; d
   }
/^Seq:/ {
   s/[^CGATcgat]*([CGATcgat]*).*/-\1-/
   h; d
   }
/^Str:/ {
   s/[^><\.]*([><\.]*).*/\1/
   s/([^>])(>)/\1X\2/g
   s/([^<])(<)/\1X\2/g
   s/([^.])(\.)/\1X\2/g
   s/X./X/g
   s/./X/
   s/((X[^X]*){7})X/\1M/

   : deleting
   x; s/.//
   t forget
   : forget
   x; s/^[^M]//
   t deleting

   s/M//

   : moving
   x; s/(.)(.*)/\2\1/
   t forget2
   : forget2
   x; s/^[^X]//
   t moving

   g; s/.*-//
   }
' | sed -E '
/^Anticodon:/ { h; d}
/^Anticodon:/ ! {
   s/^/Seq: /
   s/$/, /
   G
   s/\n//
   }
'

Это работает так:

  1. Первыйsed

    • Строки, не начинающиеся с Type:, Seq:или Str:, удаляются.
    • Для строки, начинающейся с Type:, извлекается и печатается информация Anticodon:.
    • Для строки, начинающейся с Seq:, полезная строка, такая как CGAT…, извлекается и вставляется с -символами (, они будут полезны позже ). Результат сохраняется в резервном пространстве.
    • Для строки, начинающейся сStr::
      • Извлекается полезная строка >>...<<….
      • Xвставляется всякий раз, когда изменяется последовательность; последовательные символы удаляются; Xзаменяет первый символ. В результате вместо первого символа каждого «шаблона» стоит X.
      • 8-й Xзаменяется на M.
      • Цикл
      • deletingпереключается между двумя строками и удаляет начальные символы один за другим, пока не встретится M. Когда встречается M, другая строка уже была сокращена один лишний раз. Чтобы компенсировать это, ранее было добавлено опережение -.
      • movingпетли также переключаются между двумя линиями. Он перемещает символы CGATв конец один за другим, поэтому они появляются после завершающего -. Тот же цикл удаляет символы из строки «шаблон» один за другим, пока не встретится X. Как и в случае с Mранее, когда встречается X, другая строка уже была сдвинута один лишний раз. Чтобы компенсировать это, Mбыл удален командой вне цикла (s/M//).
      • Нужная строка теперь находится после -(, которая раньше была конечным-)в удерживаемом пространстве. Копируем его в пространство паттернов, удаляем все до -. Результат распечатывается.
  2. Второйsed

    • Он предназначен для размещения -данных обработки :, для добавления метки, для форматирования, для сборки одной строки на запись.
2
27.01.2020, 20:16

Мои два цента

while IFS= read -r line; do
  [[ "$(echo $line | grep "Type:")" ]] && codon="$(echo $line | cut -d' ' -f4)" && start="$(echo $line | cut -d' ' -f6)" && type="$(echo $line | cut -d' ' -f2)" && continue
  [[ "$(echo $line | grep "Seq:")" ]] && seq="${line##Seq: }" && continue
  if [[ -n "$seq" && -n "$codon" ]]; then 
    pos="${start%-*}" && pos="$((${pos}-3))"
    echo Seq: "${seq:$pos:7}" Codon: "$codon" Type: "$type"
    seq=
    codon=
    continue
  fi
done < file

Выход:

Seq: CTCACAC Codon: CAC Type: Val
Seq: CTGAAGA Codon: GAA Type: Phe
Seq: CTGCCAC Codon: GCC Type: Gly
Seq: TTTACAC Codon: TAC Type: Val
Seq: CTGATAA Codon: GAT Type: Ile
Seq: CTGATAA Codon: GAT Type: Ile
Seq: CTGATAA Codon: GAT Type: Ile
Seq: CTTCAAA Codon: TCA Type: SeC

Найдите строку, начинающуюся с «Тип», и извлеките «Тип», «кодон» и «позиция (с 33 -35 до 33 )«

[[ "$(echo $line | grep "Type:")" ]] && codon="$(echo $line | cut -d' ' -f4)" && start="$(echo $line | cut -d' ' -f6)" && type="$(echo $line | cut -d' ' -f2)" && continue

Возьмите строку, начинающуюся с "Seq :", и извлеките последовательность ДНК:

[[ "$(echo $line | grep "Seq:")" ]] && seq="${line##Seq: }" && continue

Если установлены обе переменные $seq и $codon, распечатайте результат, затем отключите переменные и продолжите:

if [[ -n $seq && -n $codon ]]; then 
  pos="${start%-*}" && pos="$((${pos}-3))"
  echo Seq: ${seq:$pos:7} Codon: $codon Type: $type
  seq=
  codon=       
  continue
fi
0
27.01.2020, 20:16

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

$ perl -F\\n -l -00 -nae '
    $F[-1] =~ /^Str:\s+((.)\2*){7}((.)\4*)/g;
    my $c = substr($F[-2],pos($F[-1])-length($3),length($3));
    my $a = substr($c, 2, 3);
    print "seq:$c anti:$a";
' file.gene

seq:CTCCCAC anti:CCC

Краткое пояснение:

Each record is a paragraph. Then that 

запись разбита на символы новой строки и результирующие фрагменты хранятся в нулевом индексированный массив @F. Последний элемент $F[-1]является затем сканируется на наличие повторяющихся последовательностей.

((.)\1*) is a regex for one set if 

последовательных символов. Применить фигурные скобки {7} к этому n u получите 7 таких последовательностей. То Следующим будет 8-й, и чего мы хотим.

0
27.01.2020, 20:16

Теги

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