Eu tenho um arquivo (bigfile.txt), uma das colunas se parece com isso
NW_017095471.1 Gnomon mRNA 108321 109565 . + . ID=rna34;Parent=gene27;Dbxref=GeneID:108565285,Genbank:XM_017925071.1;Name=XM_017925071.1;gbkey=mRNA;gene=LOC108565285;model_evidence=Supporting evidence includes similarity to: 7 Proteins%2C and 100%25 coverage of the annotated genomic feature by RNAseq alignments%2C including 30 samples with support for all annotated introns;product=transmembrane protein 126A;transcript_id=XM_017925071.1
ID=gene27;Dbxref=GeneID:108565285;Name=LOC108565285;gbkey=Gene;gene=LOC108565285;gene_biotype=protein_coding
ID=gene28;Dbxref=GeneID:108569527;Name=LOC108569527;gbkey=Gene;gene=LOC108569527;gene_biotype=protein_coding
ID=gene78;Dbxref=GeneID:108562956;Name=LOC108562956;gbkey=Gene;gene=LOC108562956;gene_biotype=protein_coding
Eu tenho uma lista separada:
gene27
gene28
Eu quero pegar cada linha e grep o campo ID e depois retornar o 'LOC#' que segue "Name=".
gene=$line
`grep $gene";" bigfile.txt | sed -e 's/Name=
Para retornar
LOC108565285
LOC108569527
Como faço para extrair apenas essa parte?
Supondo que este seja o 9º campo delimitado por tabulação de um arquivo GFF (o campo "atributos"), você pode extrair o valor do
gene
atributo correspondente a umID
atributo específico (lido de um arquivo separado) assim comawk
:Executando isso em um arquivo GFF chamado
file.gff
contendo os dados fornecidos na coluna 9 e com a lista de ID do gene emid.list
:A lista de IDs de genes é lida a partir do primeiro arquivo no
FNR == NR
bloco noawk
código, enquanto o último bloco está processando o campo de atributo de linhas de recurso de gene (somente) no segundo (e todos os posteriores) arquivos fornecidos na linha de comando.O
awk
código assume que os atributosID
egene
do arquivo GFF contém apenas um único valor (não uma lista de valores delimitada por vírgulas) e que os valores não são citados.Para obter a saída como uma lista de nomes de genes e IDs de genes (duas colunas), altere a
print gene
instrução paraprint id, gene
.Isso precisa de refatoração, mas deve fazer o que você deseja:
Eu usaria uma abordagem um pouco diferente. Primeiro, extraia apenas os campos ID e Nome:
Em seguida, filtre isso usando a lista de IDs de destino:
Ou, se você quiser apenas o
LOC....
valor, e supondo que tenha GNUgrep
:Seguro. Simples. Curto.
O nome
bigfile.txt
sugere que não queremos fazer grep várias vezes por ele, mas fazê-lo de uma só vez. Então eu prefiro uma tentativa como @Kusalananda: colete todos os IDs de genes para extrair e depois escanear uma vez pelo arquivobigfile
. Para tal tarefa eu prefirosed
, já que você não precisa lidar com programação como variáveis, arrays e loops, apenas deixe a ferramenta fazer o trabalho:E aqui está a explicação:
/^gene[0-9]*$/
é um padrão para selecionar linhas da lista: apenasgene
com um número{s/$/;/;H;d;}
é executado apenas para as linhas acima:s/$/;/
anexa a;
,H
anexa esta linha modificada ao espaço de espera ed
interrompe o processamento adicional e exclui a linhabigfile.txt
e o espaço de espera é preenchido com todos os geneIDs. AgoraG
anexa esta lista ao espaço padrão/ID=\(gene[0-9]*;\).*\n\1/
seleciona linhas onde o IDgene[0-9]*
é repetido (\1
refere-se à string dentro do primeiro par de\(\)
) após uma nova linha, portanto, um ID que está presente na lista!d
inverte a seleção e exclui, todas as linhas sem correspondência são excluídasgene
campo:s/.*gene=\(LOC[0-9]*\);.*/\1/
Feito pelo script simples abaixo
comando
resultado
Tente isso
Tente isso,
grep -o 'Name=[^;]*'
com grep o padrão começa com "Name=" e termina imediatamente ";"sed 's/Name=//g';
basta remover o padrão que não é necessário conforme sua exigência.