Как объяснил пользователь 55518, у вас, вероятно, есть пробелы в вашем файле учетных данных, даже если вы их не видите. Если вы редактировали свой файл учетных данных в Windows, у вас, вероятно, есть \r
в конце ваших строк, и это вызывает ошибку 13.
Может быть, просто:
< 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
)}
}'
(здесь печатается строка, если найден хотя бы один атрибут (, в отличие от всех запрошенных атрибутов в других подходах )).
В идеале, поскольку данные представлены в формате 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