Ajuda básica do grep / awk - extraindo todas as linhas contendo uma lista de termos de um arquivo em um arquivo separado

5

Eu tenho dois arquivos genelist.txt e data.txt . genelist.txt simplesmente contém uma única coluna de ~ 500 nomes de genes, enquanto data.txt é um arquivo delimitado por tabulações que contém ~ 1000 colunas (as amostras) e ~ 30.000 linhas (nomes de genes). O esquema geral de data.txt é descrito abaixo.

       Sample 1 Sample 2 Sample 3 Sample 4  Gene A      1.04       1.81        1.92        0.45     Gene B      1.11       1.12        1.32        0.92     Gene C      0.72       0.71        0.85        1.12     Gene D      1.19       1.42        0.13        0.32   

Eu preciso extrair cada linha (a linha inteira, ou seja, todas as amostras) de data.txt contendo cada um dos ~ 500 nomes de genes em genelist.txt e ter essas linhas extraídas em um arquivo separado. Fui avisado para usar o grep ou o awk e procurei como fazer isso, mas como um simples biólogo com pouca ou nenhuma experiência em codificação, estou tendo um pouco de dificuldade. Seria possível que alguém explicasse como isso é feito, e esperamos que forneça algum código para que eu comece.

Também seria interessante se a extração retornasse apenas termos que correspondessem ao nome do gene inteiro em genelist.txt . Por exemplo, se eu tivesse ABC123 mas não ABC1234 em genelist.txt , gostaria que apenas ABC123 fosse extraído e não ABC1234 .

Além disso, depois disso, como eu verificaria se os genes de genelist.txt não estavam incluídos na extração? (por exemplo, alguns genes podem ser nomeados incorretamente, então eu teria que voltar e extraí-los novamente com sua alternativa e / ou nome correto).

    
por DiscoA 04.07.2016 / 06:35

3 respostas

5

Para extrair as linhas de data.txt com os genes listados em genelist.txt :

grep -w -F -f genelist.txt data.txt > newdata.txt

grep opções usadas:

  • -w informa grep para corresponder somente palavras inteiras (por exemplo, ABC123 também não corresponderá a ABC1234 ).
  • -F procura por sequências fixas (texto simples) em vez de expressões regulares
  • -f genelist.txt leu padrões de pesquisa do arquivo

Se você quiser também a linha de cabeçalho (Amostra 1, Amostra 2, etc):

grep -w -F -f genelist.txt -e Sample data.txt > newdata.txt
  • -e Sample também procura "Amostra"

Para encontrar linhas em genelist.txt que não estão em newdata.txt :

grep -v -w -F -f <(sed -E -e 's/(\t|  +).*//' newdata.txt) genelist.txt
  • -v inverte a pesquisa, imprime linhas não correspondentes.

O resto das opções do grep são as mesmas, mas ao invés de usar um arquivo com a opção -f , ele está usando algo chamado Substituição de processos (Consulte também ), que permite usar um comando no lugar de um arquivo real. Qualquer saída criada pelo comando é tratada como o conteúdo do "arquivo".

Nesse caso, estamos usando o comando sed -E -e 's/(\t| +).*//' newdata.txt , que produz cada linha de newdata.txt depois de excluir tudo primeiro do primeiro caractere TAB ou do primeiro par de espaços que ele vê. Em outras palavras, o primeiro campo (por exemplo, "Gene A"). Eu tive que usar TAB ou espaço duplo porque a) eu não tinha certeza se seus dados eram separados por espaços ou separados por TAB e b) os primeiros campos em seu exemplo continham espaços.

sed opções usadas:

  • -E usam expressões regulares estendidas, portanto, podemos usar ( , ) e + simples, que são mais legíveis do que ter que escapar delas com \ como \( , \) , \+ .
  • -e 's/(\t| +).*//' especifica o script sed para ser aplicado à entrada (newdata.txt)

A execução desse comando em sua amostra data.txt produziria a seguinte saída:

$ sed -E -e 's/(\t|  +).*//' data.txt

Gene A
Gene B
Gene C
Gene D

De qualquer forma, a saída desse comando sed é usada como a lista de padrões de pesquisa pelo comando grep .

    
por 04.07.2016 / 07:56
3

Esse é um empreendimento sem nenhuma experiência anterior com o Linux. No entanto, acho que entendo o que você precisa e não deve ser muito difícil. Diga-me antecipadamente, este é um curso muito conciso, além de uma explicação muito básica, mas eu ficaria feliz em expor em detalhes, se não faz sentido, ou editar, se necessário.

Se você simplesmente quiser analisar o data.txt e movê-lo para o genelist.txt , basta usar cat data.txt >> genelist.txt newfile.txt . (newfile.txt é o outro arquivo que você mencionou - o nome é arbitrário).

Se você quiser imprimir as linhas para um nome específico, você pode usar cat data.txt | grep ABCD123 >> genelist.txt newfile.txt e alterar ABCD123 para o que você quiser.

Este comando SOMENTE mostrará as linhas encontradas usando o grep (como uma função de "busca", mas busca somente por linha.)

O "|" é chamado de piping e, quando acoplado ao comando "grep", atua um pouco como um filtro para o que você está procurando. ( cat zoofile.txt | grep pandas , por exemplo, procurará todas as linhas, incluindo a palavra "pandas", é um nome de arquivo "zoofile". Nota O Linux É SENSÍVEL POR CAIXA e só encontrará EXATAMENTE o que você colocar. Se você quiser TODAS as instâncias de "panda" pandas, panderoons ou pandering, você poderia usar pand *, onde * é um caractere curinga e poderia ser qualquer caractere de 0 a 255 bits de comprimento. Isso selecionaria pand para pandzzzzzzzzzz e qualquer coisa entre eles, incluindo números).

Você pode usar o awk para uma análise mais sofisticada da coluna (é uma das minhas ferramentas favoritas!), mas não parece que caberia aqui, a menos que você queira APENAS dados de uma das colunas com base em determinados parâmetros.

Finalmente, aqui está um bom lugar para aprender um pouco sobre a linha de comando. Isso pode ajudar com o grep, mas não cobre o awk.

link

Depois disso, isso deve cobrir o awk em mais detalhes. Há muitos cursos muito amplos no awk, mas eles são fáceis de se perder. Este é um site prático que demonstra mais o que você está procurando fazer.

link

EDITAR - depois de reler, eu posso ter perdido alguma coisa - você está olhando para comparar os dois arquivos e imprimir apenas coisas que combinam de um para o outro? Por favor, informe e forneça um exemplo e eu ficaria feliz em editar a minha resposta em conformidade.

    
por 04.07.2016 / 06:56
3

Para responder a sua pergunta:

fgrep -w -f genelist.txt data.txt >results.txt
  • fgrep procura sequências fixas, em vez de expressões regulares (como grep e egrep do)
  • -w indica fgrep para corresponder palavras inteiras, por isso ABC123 não corresponde a ABC1234
  • -f genelist.txt informa fgrep para ler os padrões de pesquisa de genelist.txt .

Ver quais genes de genelist.txt não foram incluídos na extração é um pouco mais complicado. Uma maneira de fazer isso:

awk '{ print $1 }' results.txt | fgrep -w -v -f - genelist.txt >outsiders.txt
  • awk '{ print $1 }' imprime a primeira coluna em um arquivo de texto; esta é a lista de genes correspondentes
  • fgrep corresponde novamente às sequências fixas
  • -w informa fgrep para corresponder a palavras inteiras
  • -v diz para imprimir linhas que não correspondem
  • -f - diz para ler a lista de padrões de stdin , que é a lista de genes correspondentes de awk .

Você também pode tornar as coisas um pouco mais eficientes eliminando duplicatas da lista de genes correspondentes antes de pesquisar, intercedendo sort -u entre awk e fgrep :

awk '{ print $1 }' results.txt | sort -u | fgrep -w -v -f - genelist.txt >outsiders.txt
    
por 04.07.2016 / 07:51

Tags