Извлечение цитируемых и помеченных данных из заданного столбца

Как объяснил пользователь 55518, у вас, вероятно, есть пробелы в вашем файле учетных данных, даже если вы их не видите. Если вы редактировали свой файл учетных данных в Windows, у вас, вероятно, есть \r в конце ваших строк, и это вызывает ошибку 13.

1
13.05.2017, 11:15
2 ответа

Может быть, просто:

< file cut -sd '"' -f2,4,8,10 | tr '"' ' '

То есть рассматривать ввод как список из"-разделенных столбцов и извлекать 2 й , 4 й , 8 й и 10 . ] й столбцов.

В GNU cutвы можете заменить | tr '"' ' 'на --output-delimiter=' '.

Это делает предположение, что символы "больше нигде в строках не появляются, что эти атрибуты gene_id, transcript_id... всегда появляются и всегда в таком порядке.

Как заметил Кусалананда, это не тот случай, когда в вашей выборке должно быть 2,4,6,8для первой строки и 2,4,8,10для остальных.

Чтобы выполнить более выразительное сопоставление :, чтобы учитывалась только 9-я ая вкладка -столбец с разделителями и чтобы были найдены правильные имена атрибутов, вы можете прибегнуть к регулярным выражениям, например с:

< file pcregrep -o1 -o2 -o3 -o4 --om-separator=' ' '(?x)
  ^(?:[^\t]*+\t){8}(?=[^\t]*? \b gene_id       \ +"([^"\t]*)")
                   (?=[^\t]*? \b transcript_id \ +"([^"\t]*)")
                   (?=[^\t]*? \b reference_id  \ +"([^"\t]*)")
                   (?=[^\t]*? \b ref_gene_id   \ +"([^"\t]*)")'

Если у вас нет pcregrepили слишком старая версия для поддержки -o1..., вы можете использовать вместо нее perl:

< file perl -lne 'print "$1 $2 $3 $4" if m{
  ^(?:[^\t]*+\t){8}(?=[^\t]*? \b gene_id       \ +"([^"\t]*)")
                   (?=[^\t]*? \b transcript_id \ +"([^"\t]*)")
                   (?=[^\t]*? \b reference_id  \ +"([^"\t]*)")
                   (?=[^\t]*? \b ref_gene_id   \ +"([^"\t]*)")}x'

Это регулярное выражение сначала соответствует первым 8 полям ((?:[^\t]*+\t){8}), а затем у нас есть 4 вида -опережающих выражений ((?=...)), поэтому мы сопоставляем эти 8 полей при условии, что последующее соответствует всем 4 видам -опережающие выражения. Каждое выражение look -forward ищет один из атрибутов и фиксирует значение (в части (...)). Эти захваченные значения затем доступны в $1, $2, $3, $4.

Таким образом, атрибуты могут располагаться в любом порядке.

Обратите внимание, что его можно обмануть такими вещами, как:

1 2 3 4 5 6 7 8 gene_id "transcript_id "...

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

Пока вы используете perl,вы также можете выполнить более формальный разбор этого 9 го поля. Что-то вроде:

< file perl -F'\t' -lane '
  my %field;
  while ($F[8] =~ /(\w+) +"(.*?)"/g) {$field{$1}=$2}
  if (%field) {
    print join " ", @field{
      qw(gene_id transcript_id reference_id ref_gene_id
    )}
  }'

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

3
27.01.2020, 23:14

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

Чтобы извлечь 9-й столбец:

$ cut -f 9 data.gtf
gene_id "strAD1.1"; transcript_id "strAD1.1.1"; reference_id "ENST00000469289"; ref_gene_id "ENSG00000243485"; ref_gene_name "MIR1302-10"; cov "0.028725"; FPKM "0.053510"; TPM "0.109957";
gene_id "strAD1.1"; transcript_id "strAD1.1.1"; exon_number "1"; reference_id "ENST00000469289"; ref_gene_id "ENSG00000243485"; ref_gene_name "MIR1302-10"; cov "0.014218";
gene_id "strAD1.1"; transcript_id "strAD1.1.1"; exon_number "2"; reference_id "ENST00000469289"; ref_gene_id "ENSG00000243485"; ref_gene_name "MIR1302-10"; cov "0.072139";

Чтобы получить из этого данные, которые нам нужны, нам нужно обрабатывать транскрипты и экзоны отдельно, поскольку их атрибуты имеют разный порядок в данных. Мы делаем это с помощью awkи выводим разные поля во входных данных в зависимости от того, содержит ли текущая строка строку exon_numberили нет:

$ cut -f 9 data.gtf | awk '/exon_number/ { print $2, $4, $8, $10; next } { print $2, $4, $6, $8 }'
"strAD1.1"; "strAD1.1.1"; "ENST00000469289"; "ENSG00000243485";
"strAD1.1"; "strAD1.1.1"; "ENST00000469289"; "ENSG00000243485";
"strAD1.1"; "strAD1.1.1"; "ENST00000469289"; "ENSG00000243485";

Затем мы удаляем двойные кавычки и точки с запятой из этого:

$ cut -f 9 data.gtf | awk '/exon_number/ { print $2, $4, $8, $10; next } { print $2, $4, $6, $8 }' | tr -d '";'
strAD1.1 strAD1.1.1 ENST00000469289 ENSG00000243485
strAD1.1 strAD1.1.1 ENST00000469289 ENSG00000243485
strAD1.1 strAD1.1.1 ENST00000469289 ENSG00000243485
3
27.01.2020, 23:14

Теги

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