Я хотел бы получить имена целых заголовков, присутствующих в другом файле fasta

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

Я также рекомендую сначала сосредоточиться на строке, начинающейся с version=, и касаться только части после символа =. Поместите свое регулярное выражение в одинарные кавычки, чтобы escape-последовательности \не были упреждающе экранированы оболочкой. Кроме того, вам не нужно использовать (и )вокруг вашего совпадения, потому что вы не сохраняете его на потом.

sed -i -r '/version=/s/=.*\.[0-9][0-9]*$/version=11.21.2/g' <filename>

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

sed  -r '/version=/s/=.*\.([^.]*)$/=11.21.2.\1/g' <filename>

Чтобы принять произвольное изменение в качестве входных данных, скажем:

newver=11.21.2
sed  -r '/version=/s/=.*\.([^.]*)$/='${newver}'.\1/g' <filename>
-1
07.04.2021, 09:50
2 ответа

Одним из способов достижения того, что вы описываете, является:

  1. Создание сопоставления с использованием второго файла с заголовками
  2. Чтение первого файла и замена совпадающих строк на соответствие из сопоставления

При использовании awk это будет, например,:

awk -F@ 'NR == FNR { if ($0 ~ /^>/) { a[$1] = $0 }; next } { if ($0 ~ /^>/ && $0 in a) $0 = a[$0]; print }' second_file_with_headers first_file

Пример:

$ cat second_file_with_headers
>TRINITY_DN100_c0_g1_i1 len=242 path=[0:0-241]@Guinardia_delicatula
AGCAATCCAAACTGCTGCAATCTGGGCTCGTGAAAACGATATGGTATTACACTTACACCGTGC
>TRINITY_DN100_c0_g1_i1 KR048205>TRINITY_DN105_c0_g1_i1 len=260 path=[0:0-259]AGCAATTCAAAGTGCTGCAATCTGGGCTCGTGAAAACGATATGTTATTACACTTACACCGTGCA
>TRINITY_DN103_c0_g1_i1 len=260 path=[0:0-259]@Luticola_sparsipunctata
AGCAATTCAAAGTGCTGCAATCTGGGCTCGTGAAAACGATATGATTTTACACTTACACCGTGCA

$ cat first_file
>TRINITY_DN100_c0_g1_i1 len=242 path=[0:0-241]
AGCAATTCAAACTGCTGCAATCTGGGCTCGTGAAAACGATATGGTATTACACTTACATCGTGCAAGACAAACAACAAGTGCGTTACGTCACGTTACGTTAATTCGTTCGTTCGTCTCTCTATTGCGTTGCGTTACGCTCTCGCCGCGGACCCAGCACCGCATACCCGCCCATACAAGTCATACAGTACACAACACAAAAACACAACCAACTATTTCCTTGGAAGAGAAAGCAAGCCCAAAAC
>TRINITY_DN105_c0_g1_i1 len=260 path=[0:0-259]
TGAAAATATTAATTCTCAACCTTTTATGCGTTGGAGAGAAAGATATTTATTTTCAATAGAGGGAGTTAATCGTGCAGCGGCAGCAAGTGGTGAAATTAAAGGACATTATTTAAATGTTACTGCAGGTACAATGGAAGACATGTACGAACGCGCCAAGATTGATGTGCCTGAGAACCACATGAATAACGAGGAGCAATACACACTTCACTACCAAGAGTACCTTGTGGGTAGCTCGGCTGGTGTGCCCAAGGATATGAAGG
>TRINITY_DN103_c0_g1_i1 len=260 path=[0:0-259]
GTTCTCTTCGGTGGCAGCCTTACGGCCGACCACCTGGTATTGTCGCATAATTCCCGCAGCAGTCATGATGTCTATTGTTTGTCGTGAAAAGAAATGAATTAAGAGAGTCATAGTTACTCCCGCCGTTTACCCGCGCTTGGTTGAATTCCTTCACTTTGACATTCAGAGCACTGGGCAGAAATCACATTGCGTCAACACCATCTCTGTTTCAACGAAATCAGCAGTATCTGTAGAAGTGTAGTTAAAACTAATATCTTTCC

$ awk -F@ 'NR == FNR { if ($0 ~ /^>/) { a[$1] = $0 }; next } { if ($0 ~ /^>/ && $0 in a) $0 = a[$0]; print }' second_file_with_headers first_file
>TRINITY_DN100_c0_g1_i1 len=242 path=[0:0-241]@Guinardia_delicatula
AGCAATTCAAACTGCTGCAATCTGGGCTCGTGAAAACGATATGGTATTACACTTACATCGTGCAAGACAAACAACAAGTGCGTTACGTCACGTTACGTTAATTCGTTCGTTCGTCTCTCTATTGCGTTGCGTTACGCTCTCGCCGCGGACCCAGCACCGCATACCCGCCCATACAAGTCATACAGTACACAACACAAAAACACAACCAACTATTTCCTTGGAAGAGAAAGCAAGCCCAAAAC
>TRINITY_DN105_c0_g1_i1 len=260 path=[0:0-259]
TGAAAATATTAATTCTCAACCTTTTATGCGTTGGAGAGAAAGATATTTATTTTCAATAGAGGGAGTTAATCGTGCAGCGGCAGCAAGTGGTGAAATTAAAGGACATTATTTAAATGTTACTGCAGGTACAATGGAAGACATGTACGAACGCGCCAAGATTGATGTGCCTGAGAACCACATGAATAACGAGGAGCAATACACACTTCACTACCAAGAGTACCTTGTGGGTAGCTCGGCTGGTGTGCCCAAGGATATGAAGG
>TRINITY_DN103_c0_g1_i1 len=260 path=[0:0-259]@Luticola_sparsipunctata
GTTCTCTTCGGTGGCAGCCTTACGGCCGACCACCTGGTATTGTCGCATAATTCCCGCAGCAGTCATGATGTCTATTGTTTGTCGTGAAAAGAAATGAATTAAGAGAGTCATAGTTACTCCCGCCGTTTACCCGCGCTTGGTTGAATTCCTTCACTTTGACATTCAGAGCACTGGGCAGAAATCACATTGCGTCAACACCATCTCTGTTTCAACGAAATCAGCAGTATCTGTAGAAGTGTAGTTAAAACTAATATCTTTCC

$

Сценарий awk можно довольно легко объяснить:

awk         # the awk program, can be gawk, mawk or any other implementation
-F@         # Sets FS="@". This tells awk to split on the @ character.
NR == FNR { if ($0 ~ /^>/) { a[$1] = $0 }; next }
   # While handling the first argument (here, second_file_with_headers)
   # For lines starting with >, store the line into an array with the part before @ as the key
   # Discard all lines in this file with 'next'
{ if ($0 ~ /^>/ && $0 in a) $0 = a[$0]; print }
   # For all other lines, meaning that we are now working on the second argument (first_file)
   # For lines starting with >, change the line into the stored version from the array if it exists
   # then print the line
second_file_with_headers
   # Use the file with the headers as the first argument
first_file
   # Use the file which needs to be updated as the second argument
0
28.04.2021, 22:56
awk -F'[@[:blank:]]+' '
NR==FNR { if(/^>/) seen[$1]=$NF; next }
        { if($1 in seen) $0=$0 "@" seen[$1]; print }' second.fasta first.fasta

с -Fмы можем указать F разделитель полей, который мы установили на @символ, а также пробелы([:blank:]Tabs/Spaces ), где они могут встречаться один -или -еще раз [...]+; поэтому поля будут разделены этими символами.

NF==FNRвсегда истинное условие в awk которое истинно для первого входного файла всегда(second.fasta файл здесь ); NRи FNRувеличиваются для каждой строки ввода, но FNRсбрасывается обратно на 1 для следующего входного файла.

это if(/^>/)условие, которое проверяет, начинается ли строка(^в регулярном выражении до начала строки )с символом >, если да, то держим последнее поле $NFв связанный массив (мы назовем егоseen)и поле #1 $1будем использовать в качестве ключей.

оператор nextпропускает обработку остальных кодов и снова переходит к началу кода; если условие NR==FNRвсе еще было истинным, он будет повторять следующий код NR==FNR {... }, иначе будет выполнен следующий блок, который выполняется во втором входном файле first.fasta , который мы проверяем, если первое поле в его можно найти в массиве seenили нет, если да, то добавить в конец этой строки значение найденного ключа и затем сделать printвсе, что есть во всей строке$0(либо обновлено, либо нет ).


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

paste -d@ first.fasta second.fasta |awk -F@ '/^>/{ $1=$1 $NF } { print $1 }'
0
28.04.2021, 22:56

Теги

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