Você está na página 1de 100

Linux intermediário

Uma abordagem prática


1a edição

David da Silva Pires


Instituto Butantan

RASCUNHO

São Paulo
13 de março de 2024
RASCUNHO
SUMÁRIO

prefácio vii
§0.1 Por que fazer Ciência de Dados na linha de comando?, viii. §0.2 Pipelines em
bioinformática, viii.

I Ciência de dados na linha de comando 1

1
RASCUNHO
linha de comando
§1.1 O ambiente da linha de comando, 5. §1.2 Listagem de arquivos e diretórios, 6.
3

2 obtenção de dados 7
§2.1 Descompactação de arquivos, 8. §2.2 Convertendo planilhas do Microsoft Excel, 9.
§2.3 Consulta a bancos de dados relacionais, 10. §2.4 Baixando dados da Internet, 11.
§2.5 Fazendo uso de APIs web, 13.

3 criação de ferramentas de linha de comando reutilizáveis 15


§3.1 Visão geral, 16. §3.2 Convertendo one-liners em scripts shell, 16.

4 polimento de dados 19
§4.1 Expressões regulares, 20. §4.2 Filtros, 20. §4.3 Awk, 20. §4.4 Sed, 22. §4.5 Os
comandos grep, egrep, fgrep e rgrep, 22. §4.6 O comando head, 23. §4.7 O comando
tail, 23. §4.8 O comando sort, 24. §4.9 O comando uniq, 25. §4.10 O comando
fmt, 25. §4.11 O comando pr, 26. §4.12 O comando tr, 27. §4.13 O comando more, 27.
§4.14 O comando less, 28.

iii
5 exploração de dados 29

II Organização de pipelines em Bioinformática: a ferramenta como


unidade 31

6 entrada 35

7 saída 37

8 relatórios 39
§8.1 HISTÓRICO DOS COMANDOS, 40. §8.2 Tempo de execução, 41.

9 scripts e jobs 45

10 outras semelhanças 49
§10.1 CONFIGURAÇÃO, 49. §10.2 Final, 50. §10.3 Remoção de arquivos , 51. §10.4
Visão geral, 52.

RASCUNHO
III Organização de pipelines em Bioinformática: para além da
ferramenta 53

11 dados brutos 55

12 dados 57
§12.1 Links simbólicos, 57. §12.2 MD5 check sum, 59. §12.3 Descompactação de dados, 61.
§12.4 Checagem: número de reads e de nucleotídeos, 61. §12.5 Remoção dos dados, 64.

13 metadados 65
§13.1 Metadados nos nomes dos arquivos, 65.

14 programas e pipelines 67
15 hubs 69

16 dados de referência 71

17 outros diretórios úteis 73


§17.1 WWW, 73.

IV Casos de uso 75

18 formatos de arquivos 77
§18.1 CSV e TSV, 77. §18.2 FASTA, 77. §18.3 FASTA 2 line, 83. §18.4 FASTQ, 83.
§18.5 BED, GFF e GTF, 83. §18.6 BAM, 83.

19 outros tópicos 87
§19.1 Submissão de resultados, 87.

V Apêndice 89

RASCUNHO
epílogo 91
RASCUNHO
PREFÁCIO

A linha de comando permite que você se torne um cientista de dados mais eficiente
e produtivo. Por meio da combinação de ferramentas de linha de comando simples,
porém poderosas, você pode rapidamente obter, explorar e modelar seus dados.
O pré-requisito para acompanhar sem dificuldades o conteúdo deste livro é que
você tenha noções básicas sobre a linha de comando do Linux. Uma introdução básica
ao assunto, tal como no livro “Introdução à linha de comando do Linux”, disponível
em http://butantan.gov.br/cbbc/cursos/introLinux, já é suficiente. Após
dominar o básico, será possível acompanhar o material apresentado neste livro, que in-
clui a introdução e explicação de conceitos e ferramentas relevantes para fazer ciência
de dados na linha de comando.

RASCUNHO
Nesta apostila você aprenderá a realizar operações que comumente estão presen-
tes no dia a dia de um bioinformata, tais como obter e processar dados a partir de
sites, servidores, planilhas eletrônicas e principalmente arquivos de texto (em formato
CSV), além de gerenciar pipelines.
Um cientista de dados pode se beneficiar da flexibilidade dada pela linha de co-
mando, tornando-se mais eficiente e produtivo. A linha de comando constitui uma
tecnologia ágil, escalável e extensível.
Este material cobre um conjunto indispensável de habilidades para lidar com dados
que permite transformar enormes conjuntos de dados de sequenciamento em desco-
bertas biológicas significativas e de modo que seja facilmente reprodutível.

O que é Ciência de Dados?

Curso da FGV: aproveitar o slide com o diagrama de Venn sobre tudo o que um cien-
tista de dados deve saber.
1. Falar um pouco de dados
não-estruturados. Podemos
vii dizer que um FASTA é
estruturado? E formatos como
BED e GFF? Mesmo sendo
estruturado, pode ter MUITOS
erros.
2. Opcional.
automatização 0.0.1 O padrão OSEMN
reprodutibilidade
0.1 Por que fazer Ciência de Dados na linha de co-
mando?
0.2 Pipelines em bioinformática
desenvolvimento de pipelines é uma atividade comum a todo profissional da área
O de Bioinformática.
Estamos em busca de automatização, trabalho em grupo, melhor aproveitamento
de espaço em disco, reprodutibilidade.
Pipelines não são específicos de Bioinformática, mas sim da Ciência da Computa-
ção. Origem no comando pipe (|) do Unix? Envolvem o encadeamento de tarefas.
Características de pipelines de Bioinformática:
• São tempo-intensivos, ou seja, levam muito tempo para rodar, dada a quantidade de
dados a ser processada geralmente ser muito grande.
• Necessitam de uma grande quantidade de parâmetros, refletindo as diversas opções
de execução diferentes de cada programa e as diferentes formas de se analisar os
dados de entrada.
Explicar o conceito de one-liners e a vantagem que se tem ao transformá-los em
scripts.
Falar do quadrado da soma de dois termos: Você consegue calcular, rapidamente,
o valor de 532 +2∗53∗47+472 ? (propor o problema com os resultados das potências e

RASCUNHO
da multiplicação; e se simplificarmos para a expressão proposta? Se lembrarmos que
o quadrado da soma de dois termos equivale à soma do quadrado do primeiro termo
com ...
Parte I

Ciência de dados
na linha de comando

RASCUNHO

1
RASCUNHO
CAPÍTULO 1
LINHA DE COMANDO

A maioria das pessoas está acostumada a interagir com um computador por meio de
uma interface gráfica, com janelas, ícones e botões. Por conta disso, interagir com um
computador através de uma interface modo texto pode ser intimidador à primeira vista.
No entanto, passado esse primeiro susto, nota-se que é possível realizar as tarefas de
maneira muito mais ágil e eficiente, além de se ter a possibilidade de usar opções dos
comandos para as quais ainda não há acesso via interface gráfica.
Neste capítulo, nós discutimos vários conceitos e ferramentas necessárias para que
você se sinta confortável ao trabalhar na linha de comando. Se, até agora, você tem

RASCUNHO
trabalhado principalmente com interfaces gráficas, a mudança pode ser bem drástica.
Não se preocupe, porém: tudo será introduzido de forma gradual até que sejam discu-
tidos tópicos mais avançados.
Algumas vantagens da linha de comando são:

Agilidade. Quando se lida com dados, são realizadas operações que possuem natu-
reza muito interativa e exploratória. A linha de comando permite isso por meio
de da avaliação imediata de comandos e de sua intrínseca proximidade com o
sistema de arquivos.

Avaliação imediata de comandos. A interação com a linha de comando se re-


sume a escrever um comando, pressionar <ENTER>, aguardar o comando
ser executado e ver o resultado da execução do comando na tela. Esse
esquema é conhecido pela sigla em inglês REPL, de read-eval-print-loop.
Ele é considerado muito eficiente e passível de rápidas mudanças, contra-
pondo-se ao ciclo editar-compilar-rodar-debugar, comumente associado a
scripts e programas. O curto ciclo de iteração do REPL permite que você
lide facilmente com seus dados.
Proximidade com o sistema de arquivos. O processamento de dados possui
como principal ingrediente o próprio conjunto de dados, que é armaze-
nado em arquivos e organizado em diretórios. A linha de comando possui
diversas ferramentas que facilitam esse acesso ao sistema de arquivos.

3
Integração. Independente das ferramentas ou das linguagens de programação que
são usadas para resolver problemas, a linha de comando sempre pode ser enca-
rada como uma tecnologia de integração e expansão, ampliando o uso de outros
programas que, porventura, já estejam sendo adotados. É possível, por exem-
plo, transformar código escrito em Python ou R em ferramentas de linha de
comando, ou então processar tipos de arquivos criados por programas ampla-
mente usados, como os de extensão .xlsx gerados pelo Excel.

Escalabilidade. Há uma grande diferença entre trabalhar na linha de comando e tra-


balhar com uma interface gráfica. Naquela, o trabalho é feito através da digita-
ção de comandos, nesta através de apontar e clicar com o mouse. Os comandos
digitados podem ser automatizados através da escrita de scripts. Isso faz com
que seja muito fácil rodar novamente um comando caso:

• um erro tenha sido cometido;


• o conjunto de dados foi alterado;
• haja a necessidade de se repetir a análise, seja por você ou por outros usuários.

Além disso, os comandos podem ser executados em dias e horários predetermi-


nados, em servidores remotos e em paralelo em várias sessões do conjunto de
dados. Todos esses últimos benefícios citados devem-se ao fato de os coman-
dos serem passíveis de automação, tornando-os escaláveis e reproduzíveis. Já
no caso de interfaces gráficas, não é tão simples automatizar posicionamento de
mouse e cliques em botões.

RASCUNHO
Extensibilidade. Apesar de as principais funcionalidades da linha de comando terem
sido criadas há várias décadas atrás, as ferramentas, que atribuem à linha de
comando um grande poder, são desenvolvidas todos os dias, conferindo uma
extensão de enorme valor. Outro fator muito importante para essa extensão é a
independência com relação a linguagens de programação: uma ferramenta de
linha de comando pode ser escrita em qualquer linguagem, desde que forneça
uma interface em modo texto. A possibilidade de combinar as diferentes fer-
ramentas, fazendo com que a saída de alguns comandos sirva de entrada para
outros programas, torna a linha de comando extremamente flexível, permitindo
a criação de novas ferramentas a partir dessas combinações e extendendo a fun-
cionalidade existente.

Ubiquidade. O fato de a linha de comando estar presente em sistemas operacionais


semelhantes ao Unix, tais como o Linux e o Mac OS X, ela pode ser encontrada
em uma quantidade enorme de computadores. Isso inclui desde laptops, desk-
tops e smartphones até servidores e supercomputadores. Muito da computação
em nuvem oferecida atualmente é executada em máquinas virtuais que rodam
Linux. Além de estar presente em todo lugar, a linha de comando está longe
de ser uma moda: sua presença e importância tem sido sólida há mais de 40
anos e certamente assim se manterá por muitas outras décadas, o que torna seu
aprendizado recompensador, incentivando-o.
1.1 O ambiente da linha de comando
Antes de colocarmos a mão na massa, vejamos uma apresentação mais alto nível do
ambiente com o qual iremos trabalhar: a linha de comando. O ambiente é basicamente
composto por quatro camadas, listadas a seguir da camada mais superior para a mais
básica.
Ferramentas de linha de comando: em primeiro lugar vêm as ferramentas de linha
de comando com as quais iremos lidar. Seu uso se faz através da digitação dos
comandos no terminal. Há diferentes tipos de ferramentas de linha de comando,
os quais serão discutidos mais adiante. Como exemplos de ferramentas que
iremos usar muito podemos citar o grep, o find, o cat e o cut.
Terminal: a segunda camada é o terminal, que é a aplicação na qual digitamos os
comandos. É no terminal que temos a figura do prompt, geralmente indicado
pelo símbolo $. O terminal é, a princípio, a entrada e a saída padrão de todo
comando, sendo necessário realizar redirecionamentos para que essa caracterís-
tica seja alterada. Tradicionalmente, é composto por teclado e tela, mas ulti-
mamente também são aceitos como dispositivos de entrada mouse e touchpad e
como dispositivo de saída janelas em um ambiente gráfico.
Shell: o shell é a segunda camada. Usamos o terminal para digitar um comando e,
após pressionar a tecla <ENTER>, o terminal envia o comando para o shell. O
shell é um programa que interpreta o comando. Há diversos tipos de shell, sendo
os mais conhecidos o bash e o zsh (lê-se “zésh”).
Sistema operacional: a quarta camada é o sistema operacional, que no nosso caso
é o Linux. Estritamente falando, Linux é o kernel do sistema operacional. É

RASCUNHO
ele que possui contato direto com o processador, a memória, os discos, a placa
gráfica e todo o restante do hardware. Também é o kernel que executa todas as
ferramentas de linha de comando. Há diversas distribuições de sistema opera-
cional que incluem o Linux como kernel, tais como Ubuntu, Debian, Red Hat,
Mint, Fedora, dentre outras.
Revisão de comandos básicos do Linux. (Falar sobre (a2 - 2ab + b2) / (a - b) = a +
b como sendo um exemplo de aplicação de uma técnica que já deve ser muito bem co-
nhecida para ser aplicada. O mesmo para os comandos que, quando bem conhecidos,
podem ser aplicados para ferramentas mais complexas.)
As diferentes formas de passar opções e argumentos para parâmetros de progra-
mas.
Atividades administrativas.
• Instalação de programas (apt, git, configure, make, cmake).
• Manutenção do sistema.
Os comandos mais importantes em Ciência de Dados no Linux.
• grep.
• sed.
• awk.
• sort.
• diff.
• comm.
• uniq.

• tr.
• cat.
• head.

• tail.
• wc.
• find.
• tsort.

• tee.

1.2 Listagem de arquivos e diretórios


Há vários comandos que podemos usar para listar os arquivos e os subdiretórios pre-
sentes em um diretório.

RASCUNHO
ls O comando ls é o mais usado e o primeiro que vem à mente quando queremos
visualizar os nomes de arquivos e diretórios.

tree O comando tree fornece apresenta o conteúdo de um diretório com um forte


apelo visual.

exa O comando exa é um substituto moderno para ambos os comandos ls (opções


--long --header) e tree (opção --tree). Assim como com o comando tree, é
possível determinar o nível de profundidade na listagem do conteúdo de uma árvore
de diretórios (opção --level=n, em que n é o nível de profundidade). Sua principal
característica envolve a apresentação das listagens com o uso intenso de cores, o que
pode facilitar a identificação de diferenças e semelhanças entre os arquivos e diretó-
rios listados. Para quem usa git, essa ferramenta permite rastrear um arquivo novo
adicionado em um determinado repositório Git (opção --git).
O padrão OSEMN.
CAPÍTULO 2
OBTENÇÃO DE DADOS

Para processar qualquer conjunto de dados em um computador é preciso, antes de


tudo, ter acesso aos dados. Esse acesso pode se dar de diversas formas, dentre elas:
• Baixar os dados a partir de um site na internet.
• Copiar os dados a partir de (ou para) um servidor.
• Extrair dados a partir de um arquivo (e.g., uma planilha eletrônica).
• Gerar seus próprios dados, seja através da medida de sensores ou por meio de pes-

RASCUNHO
quisas.
O primeiro passo é, portanto, obter os dados a serem processados de modo que
eles possam ser acessados diretamente na máquina em serão analisados. Além disso,
os dados devem estar em um formato com o qual possamos trabalhar com eles.
A interface universal é o modo texto. As ferramentas de linha de comando que são
classificadas como filtros recebem texto como entrada e produzem texto como saída.
Essa padronização na interface permite que tais ferramentas trabalhem tão bem em
conjunto. Ainda assim, mesmo texto puro pode se apresentar de diversas formas.
Dados podem ser obtidos de diversas formas:
• baixando-os a partir de um servidor;
• consultando-os um banco de dados;
• conectando com uma API web.
Não obstante, os dados às vezes podem estar compactados ou em um formato
binário, como o do Microsoft Excel.
• Baixar dados da internet (wget e curl).
• Copiar dados de e para um servidor (scp).
• Descompactação de arquivos (tar, gunzip).
• Conversão de planilhas Excel em dados do tipo texto (in2csv).

7
2.1 Descompactação de arquivos
O motivo mais comum para se trabalhar com arquivos compactados é fazer um melhor
uso do espaço ocupado em disco. Arquivos menores também são transferidos mais ra-
pidamente entre um computador e outro ou até mesmo entre dispositivos ou diretórios
de um mesmo computador. Arquivos que contém valores repetidos muitas vezes (tais
como as palavras em um arquivo de texto ou os nucleotídeos em um arquivo que arma-
zena a sequência de um genoma), são arquivos com os quais se consegue uma ótima
taxa de compactação dos dados, tendo seu tamanho reduzido consideravelmente.
Um outro motivo que incentiva o uso de arquivos compactados, mas que não ne-
cessariamente realiza uma compactação, é o encapsulamento de uma coleção de ar-
quivos em um só. Assim, é possível copiar, mover ou transferir vários arquivos de
uma só vez, usando apenas o arquivo que encapsula todos.
Algumas extensões de arquivos compactados são:
• .tar
• .gz
• .tar.gz ou .tgz
• .bz
• .tar.bz
• .zip
• .rar

RASCUNHO
Os comandos mais usados para compactar e descompactar arquivos são:
• tar
• gzip e gunzip
• bzip2 e bunzip2
• zip e unzip
• rar e unrar
Para descompactar um arquivo com a extensão .tar.gz você pode executar o
seguinte comando:
$> tar zxvvf arquivo.tar.gz
O comando tar é um exemplo de que as opções podem ser passadas sem o uso do
hífen. No exemplo acima, as seguintes opções foram usadas:
z: Usa o comando gzip para descompactar o arquivo.
x: Os arquivos serão extraídos a partir da coleção de arquivos.
vv: Duplamente verboso, gerando uma listagem semelhante à do comando ls -l.
f: A entrada corresponde ao conteúdo do arquivo que é passado como argumento.
Com o tempo, o usuário acaba se acostumando com as opções mais comuns do co-
mando tar. Há, no entanto, uma forma mais conveniente ainda de descompactar
arquivos: o comando unpack.
Em vez de se recordar das diferentes ferramentas de linha de comando e todas
as suas opções, pode-se fazer uso do script unpack, o qual se baseia na extensão
dos arquivos que se deseja descompactar e chama o programa apropriado, podendo
ser usado para descompactar diferentes formatos de arquivo. Para descompactar um
arquivo, basta passá-lo como argumento para o comando.

$> unpack arquivo.tar.gz

2.2 Convertendo planilhas do Microsoft Excel


O programa de planilha eletrônica Excel, da Microsoft, é muito usado por muitas pes-
soas para lidar com pequenos conjuntos de dados e realizar cálculos sobre estes. Por
esse motivo, muitos dados são armazenados em planilhas do Excel, cujo formato de
arquivo pode ser binário proprietário (.xls) ou uma coleção de arquivos XML com-
pactados (.xlsx). Em ambos os casos, os dados não estão diretamente disponíveis
para uso de ferramentas de linha de comando. Seria uma vergonha se não fôssemos
capazes de usar esses valiosos conjuntos de dados somente porque se encontram ar-
mazenados dessa forma.
Felizmente há uma ferramenta de linha de comando chamada in2csv que é capaz
de converter planilhas do Excel para arquivos no formato CSV (acrônimo para o termo
em inglês Comma-Separated Values ou Character-Separated Values). O formato CSV
é bem simples e consiste nos seguintes três requisitos:

RASCUNHO
① Cada registro localiza-se em uma linha separada, delimitada por uma quebra de
linha, que em ambientes Windows consiste em dois sinais: CR (de carriage return,
“retorno de carro”, em uma clara referência ao retorno da cabeça de impressão em
antigas impressoras de linha) e LF (de line feed , “alimentação de linha”).1

② O último registro de um arquivo pode ter ou pode não ter uma quebra de linha ao
final.

③ Pode haver uma linha de cabeçalho opcional localizada na primeira linha do ar-
quivo com o mesmo formato das linhas de registro normais. Este cabeçalho contém
nomes correspondentes aos campos (colunas) do arquivo e deve conter o mesmo
número de campos que os registros do restante do arquivo contêm.

Para extrair os dados de uma planilha do Excel e visualizá-los no formato CSV,


basta passar o nome do arquivo da planilha como argumento para o comando in2csv.
A listagem do conteúdo é enviada para a saída padrão (tela), de modo que na maioria
das vezes é conveniente redirecionar a saída padrão para um arquivo com a extensão
csv.

$> in2csv planilha.xlsx


$> in2csv planilha.xlsx > planilha.csv
1 Em ambientes Linux, a quebra de linha é sinalizada por apenas um símbolo, representado por \n e

chamado de new line, “nova linha”.


O formato do arquivo é automaticamente determinado por sua extensão (xlsx no
exemplo). Para usar o comando in2csv em um pipeline em que ele recebe dados via
pipe, deve-se especificar o formato da entrada explicitamente.
O formato CSV não é muito agradável para leitura. Não é fácil, por exemplo,
distinguir itens de linhas diferentes que pertençam a uma mesma coluna. Para facilitar
a visualização podemos enviar a saída do comando in2csv para o comando csvlook,
que formatará os dados em uma tabela.

$> in2csv planilha.xlsx | csvlook

Se, no entanto, a tabela possuir linhas muito extensas, a ponto de não ser possível
mostrar todo o conteúdo de cada linha em apenas uma linha na tela, podemos paginar
a saída do comando csvlook com o comando less usando a opção -S.

$> in2csv planilha.xlsx | csvlook | less -S

Outra solução é usar o comando csvcut para selecionar um subconjunto das co-
lunas a serem exibidas, de modo que a tabela “caiba” na tela.

$> in2csv planilha.xlsx |


csvcut -c chrom,chromStart,chromEnd,strand | csvlook

A opção -c do comando csvcut recebe como argumento a lista de títulos das colunas
de interesse separados por vírgula.
Uma planilha pode conter várias abas. Por padrão, o comando in2csv extrai os
dados da primeira aba da planilha. Para extrair os dados de uma aba diferente, é ne-
cessário passar o nome da aba como argumento para o parâmetro da opção --sheet.
As ferramentas in2csv, csvcut e csvlook fazem parte do Csvkit, que é uma

RASCUNHO
coleção de várias valiosas ferramentas de linha de comando para trabalhar com dados
no formato CSV.
Uma abordagem alternativa ao comando in2csv é abrir a planilha eletrônica no
programa Microsoft Excel ou em um programa equivalente de código-fonte aberto
(tais como o LibreOffice Calc, o Gnumeric ou o WPS), e exportá-lo manualmente
para o formato CSV. Enquanto essa estratégia funciona perfeitamente para um caso
único, as desvantagens claras são que ela não é escalável para múltiplos arquivos,
muito menos é passível de automatização. Além disso, quando se trabalha na linha de
comando de um servidor remoto, raramente programas que fazem uso de interfaces
gráficas estão disponíveis.

2.3 Consulta a bancos de dados relacionais


Muitos dados de nosso interesse são armazenados em bancos de dados relacionais.
Como exemplos de bancos de dados relacionais podemos citar o MySQL, o Post-
greSQL e o SQLite. Cada um deles possui uma forma levemente diferente para aces-
sar os dados. Alguns fornecem uma ferramenta ou interface de linha de comando,
enquanto outros não. Não obstante, não há muita consistência em relação a seu uso e
a saída de dados.
Felizmente há uma ferramenta de linha de comando chamada sql2csv, que faz
parte da suíte de ferramentas Csvkit. Com ela é possível executar consultas em di-
ferentes tipos de bancos de dados, incluindo MySQL, Oracle, PostgreSQL, SQLite,
Microsoft SQL Server e Sybase. A saída do comando sql2csv é, como seu próprio
nome indica, no formato CSV.
Nós podemos obter dados a partir de bancos de dados relacionais executando uma
consulta do tipo SELECT. O comando sql2csv também suporta consultas do tipo
INSERT, UPDATE e DELETE mas para a obtenção de dados somente o SELECT é usado.
Para selecionar um conjunto específico de dados a partir de um banco de dados SQLite
chamado iris.db, podemos executar o comando sql2csv da seguinte forma:

sql2csv --db ’sqlite:///data/iris.db’ \


--query ’SELECT * FROM iris WHERE sepal_length > 7.5’
sepal_length,sepal_width,petal_length,petal_width,species
7.6,3.0,6.6,2.1,Iris-virginica
7.7,3.8,6.7,2.2,Iris-virginica
7.7,3.6,6.9,2.3,Iris-virginica
7.7,3.8,6.7,2.0,Iris-virginica
7.9,3.8,6.4,2.0,Iris-virginica
7.7,3.0,6.1,2.3,Iris-virginica

O comando acima seleciona todas os registros cujo valor do atributo sepal_length


é maior que 7,5.

2.4 Baixando dados da Internet


A Internet pode ser considerada, sem sombra de dúvidas, a maior fonte de dados.
Esses dados são disponibilizados de diversas formas, em vários formatos e usando

RASCUNHO
diferentes protocolos. A ferramenta de linha de comando cURL pode ser considerada
o canivete suíço quando se trata de baixar dados da Internet.
Quando acessamos um endereço da Internet, também conhecido como URL (do
inglês uniform resource locator), geralmente o fazemos por meio de um navegador de
Internet. Assim, os dados são baixados e interpretados, de modo que um site HTML é
renderizado, um áudio em MP3 é tocado e um documento em PDF é exibido. Quando,
no entanto, usamos o cURL para acessar uma URL, os dados são baixados e enviados
para a saída padrão. Com isso, outras ferramentas de linha de comando podem ser
usadas para processar os dados.
A execução mais simples do comando curl é chamá-lo especificando simples-
mente a URL como argumento. Por exemplo, para baixar o conteúdo do livro As
aventuras de Huckleberry Finn, de Mark Twain, a partir do Projeto Gutenberg, pode-
se rodar o seguinte comando:

$> curl https://www.gutenberg.org/files/76/76-0.txt

Por padrão, o comando curl exibe uma barra de progresso que mostra a taxa de
download e a expectativa de quanto tempo falta para finalizar o processo. No caso
de os dados baixados serem usados, via pipe, como entrada para um outro programa,
certifique-se de especificar a opção -s, de silencioso, de modo que a exibição da barra
de progresso seja desabilitada.

$> curl -s https://www.gutenberg.org/files/76/76-0.txt


Para salvar os dados baixados, pode-se tanto especificar o arquivo de saída a ser
gravado com a opção -o quanto simplesmente fazer um redirecionamento da saída
padrão.
$> curl -s https://www.gutenberg.org/files/76/76-0.txt \
-o data/finn.txt
$> curl -s https://www.gutenberg.org/files/76/76-0.txt \
> data/finn.txt
Os exemplos dados até agora podem ser usados tanto em URLs que usam os pro-
tocolos HTTP e HTTPS quanto para baixar dados de um servidor FTP. No caso de a
URL ser protegida com senha, pode-se especificar um nome de usuário e senha como
a seguir:
$> curl -u username:password ftp://host/file
No caso de a URL especificada consistir em um diretório, o comando curl listará o
conteúdo do diretório.
Quando se acessa uma URL encurtada, tais como as que começam com http://
bit.ly/ ou http://t.co/, os navegadores de Internet fazem um redirecionamento
automático para a correta localização. Com o comando curl, no entanto, é preciso
especificar a opção -L (ou --location) para que o redirecionamento ocorra.
$> curl -L j.mp/locatbbar
Caso a opção -L não seja especificada, a saída obtida será:
$> curl j.mp/locatbbar
<html>

RASCUNHO
<head><title>Bitly</title></head>
<body><a
href="http://en.wikipedia.org/wiki/List_of_countries_and_territories_by_border/
area_ratio">moved here</a></body>
</html>
Especificando a opção -I (ou --head), o comando curl obtém somente o cabe-
çalho HTTP como resposta:
$> curl -I j.mp/locatbbar
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 14 Feb 2022 16:24:03 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 170
Cache-Control: private, max-age=90
Location:
http://en.wikipedia.org/wiki/List_of_countries_and_territories_by_border/
area_ratio
Via: 1.1 google
A primeira linha do resultado indica o código HTTP de status, que é 301 neste caso
(permanentemente movido). Também está presente o local para o qual essa URL redi-
reciona: http://en.wikipedia.org/wiki/List_of_countries_and_territories_
by_border/area_ratio. A inspeção do cabeçalho e a obtenção do código de status
é uma ferramenta de debugação muito útil no caso de o comando curl não fornecer o
resultado desejado. Outros códigos de status HTTP comuns são 404 (não encontrado)
e 403 (acesso negado).

2.5 Fazendo uso de APIs web


Na seção anterior foi explicado como baixar arquivos individuais a partir da Internet.
Outra forma que dados podem ser obtidos da Internet é através de uma API (sigla
para application programming interface) web. O número de APIs que vêm sendo
oferecidas por organizações está crescendo a uma taxa nunca vista, o que significa a
disponibilização de muitos dados interessantes.
APIs web não têm a intenção de apresentar os dados em um formato visivelmente
bonito, como ocorre em sites na Internet. Em vez disso, muitas APIs web fornecem
dados em um formato estruturado, tal como JSON ou XML. A obtenção de dados em
um formato estruturado possui a vantagem de que os mesmos podem ser processados
por outras ferramentas, tal como jq. Por exemplo, a API fornecida por https://
randomuser.me/api devolve dados na seguinte estrutura JSON:

$ curl -s https://randomuser.me/api | jq ’.’


{
"results": [
{
"gender": "female",
"name": {

RASCUNHO
"title": "Ms",
"first": "Regina",
"last": "Coleman"
},
"location": {
"street": {
"number": 8238,
"name": "Hunters Creek Dr"
},
"city": "Seymour",
"state": "New Mexico",
"country": "United States",
"postcode": 11498,
"coordinates": {
"latitude": "88.0844",
"longitude": "26.6853"
},
"timezone": {
"offset": "+5:30",
"description": "Bombay, Calcutta, Madras, New Delhi"
}
},
"email": "regina.coleman@example.com",
"login": {
"uuid": "c2ebd6d9-0ae1-439e-b1b9-60c52d416655",
"username": "organicgoose133",
"password": "probes",
"salt": "N6glM4Th",
"md5": "8c166d5860b64cfdb04c66d640fd11c5",
"sha1": "503ee394b37e69fdbe011e95dd2b21a1fbd89c4f",
"sha256":
"3cf0e38ce5936130f55f3677734e97563ab64088dc9221544a25f8f61372bb52"
},
"dob": {
"date": "1988-01-14T12:06:05.463Z",
"age": 34
},
"registered": {
"date": "2008-06-14T15:51:29.809Z",
"age": 14
},
"phone": "(820)-333-3949",
"cell": "(925)-777-1890",
"id": {
"name": "SSN",
"value": "372-52-2990"
},
"picture": {
"large": "https://randomuser.me/api/portraits/women/14.jpg",

RASCUNHO
"medium": "https://randomuser.me/api/portraits/med/women/14.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/women/14.jpg"
},
"nat": "US"
}
],
"info": {
"seed": "4ee80a60e13f9355",
"results": 1,
"page": 1,
"version": "1.3"
}
}

Os dados são passados, via pipe, para a ferramenta de linha de comando jq, de modo
a exibi-los em um formato agradável. O comando jq possui muitas outras possibili-
dades, as quais serão melhor exploradas em um capítulo à frente.
Algumas APIs web fornecem dados em fluxo contínuo. Isso significa que, uma vez
que você se conecta a elas, os dados continuarão a fluir para sempre. Um exemplo bem
conhecido é o Twitter Firehose, o qual fornece constantemente todos os tweets envia-
dos em torno do mundo. Felizmente, muitas das ferramentas de linha de comando que
usamos operam em modo de fluxo contínuo, de modo que também podemos fazer uso
desse tipo de dado.
CAPÍTULO 3
CRIAÇÃO DE FERRAMENTAS
DE LINHA DE COMANDO
REUTILIZÁVEIS

Por todo o livro, usamos diversos comandos e pipelines que cabem basicamente em
uma linha: os chamados one-liners. Ser capaz de executar tarefas complexas com
apenas um one-liner é uma característica poderosa da linha de comando e constitui

RASCUNHO
uma experiência diferente da de escrever programas.
Algumas tarefas são necesssárias somente uma vez enquanto outras são executadas
com uma maior frequência. Da mesma forma, algumas tarefas são muito específicas
ao passo que outras podem ser generalizadas. Caso você perceba que precisará re-
petir um determinado one-liner com uma certa frequência, vale a pena torná-lo uma
ferramenta de linha de comando. Tanto one-liners quanto ferramentas de linha de
comando têm seu uso. Reconhecer a oportunidade requer prática e habilidade. A van-
tagem de uma ferramenta de linha de comando é que você não precisa se lembrar de
todo o one-liner e ela pode melhorar a legibilidade caso você a inclua em algum outro
pipeline.
O benefício de se trabalhar com uma linguagem de programação é que você pos-
sui o código em um arquivo. Isso significa que você pode facilmente reutilizar esse
código. Se o código possui parâmetros, ele pode inclusive ser aplicado a outros pro-
blemas que seguem um padrão similar.
Ferramentas de linha de comando possuem o melhor dos dois mundos: elas podem
ser usadas a partir da linha de comando, aceitam parâmetros e só precisam ser criadas
uma vez. Neste capítulo, você se tornará familiar com a criação de ferramentas de
linha de comando reutilizáveis de duas formas. Primeiro, será explicado como tornar
one-liners em ferramentas de linha de comando reutilizáveis. Ao adicionar parâmetros
a nossos comandos, pode-se adicionar a mesma flexibilidade que uma linguagem de
programação oferece. Subsequentemente, será demonstrado como criar ferramentas
de linha de comando reutilizáveis a partir de código que você tenha escrito em uma

15
linguagem de programação. Seguindo a filosofia Unix, seu código pode ser combi-
nado com outras ferramentas de linha de comando, que podem ter sido escritas em
uma linguagem completamente diferente. O foco será dado em duas linguagens de
programação: Python e R.
Esteja certo de que a criação de ferramentas de linha de comando reutilizáveis
o torna mais eficiente e produtivo a longo prazo. Gradualmente você construirá sua
própria caixa de ferramentas a partir da qual você poderá extrair ferramentas existentes
e aplicá-las a novos problemas que você encontrou previamente em uma forma similar.
Requer prática para ser capaz de reconhecer a oportunidade de tornar um one-liner ou
código existente em uma ferramenta de linha de comando.
Para converter um one-liner em um script shell, precisamos usar um pouco de
conhecimento sobre como se escreve scripts em bash. Com o uso de apenas alguns
conceitos básicos já é possível concluir a tarefa. Ainda assim, é recomendável adquirir
um conhecimento maior da linguagem através de livros e cursos.

3.1 Visão geral


Neste capítulo você aprenderá a:
• converter one-liners em scripts shell;
• fazer com que códigos já existentes escritos em Python ou R façam parte da linha
de comando.

3.2 Convertendo one-liners em scripts shell

RASCUNHO
Nesta seção, iremos explicar como converter um one-liner em uma ferramenta de linha
de comando reutilizável. Considere o seguinte one-liner:
$> curl -s https://www.gutenberg.org/files/76/76-0.txt |
tr ’[:upper:]’ ’[:lower:]’ |
grep -oE ’\w+’ |
sort |
uniq -c |
sort -nr |
head -n 10
6443 and
5098 the
3665 i
3258 a
3024 to
2567 it
2087 t
2046 was
1848 he
1781 of
Em resumo, como você deve ter adivinhado pela saída, este one-liner devolve as dez
palavras mais frequentes na versão ebook do livro “Adventures of Huckleberry Finn”.
Esta tarefa é concluída por meio da execução das seguintes ações:
① Baixar o ebook usando o curl.
② Converter o texto inteiro para letras minúsculas usando o tr.
③ Extrair todas as palavras usando o grep e colocar cada palavra em uma linha se-
parada.
④ Ordenar essas palavras em ordem alfabética usando o sort.
⑤ Remover todas as linhas duplicadas e contar com que frequência cada palavra apa-
rece na lista usando o uniq.
⑥ Ordenar essa lista de palavras únicas por sua contagem em ordem descendente
usando o sort.
⑦ Manter somente as 10 linhas do topo (i.e., palavras) usando o head.
Cada ferramenta de linha de comando usada neste one-liner possui um manual.
Assim, no caso de você querer conhecer um pouco mais sobre, digamos, grep, você
pode rodar man grep a partir da linha de comando. As ferramentas de linha de co-
mando tr, grep, uniq e sort serão discutidas em maiores detalhes no próximo ca-
pítulo.
Não há nada de errado em rodar este one-liner somente uma vez. No entanto,
imagine se você quiser encontrar as 10 palavras mais frequentes de todos os ebooks do
Projeto Gutemberg. Ou então imagine que queiramos as 10 palavras mais frequentes
de um site de notícias a cada uma hora. Nesses casos, seria melhor ter esse one-liner
como um bloco de construção separado que possa fazer parte de algo maior. Seria
ótimo se pudéssemos flexibilizar esse one-liner em termos de parâmetros, de modo a
torná-lo um script shell.

RASCUNHO
Já que usamos o Bash como nosso shell, o script será escrito na linguagem de
programação Bash. Isso nos permite tomar o one-liner como ponto inicial e ir gradu-
almente melhorando ele. Para transformar esse one-liner em uma ferramenta de linha
de comando reutilizável, seguiremos os próximos seis passos:
① Copiar e colar o one-liner em um arquivo.
② Adicionar permissão de execução.
③ Definir o chamado shebang.
④ Remover a parte fixa de entrada.
⑤ Adicionar um parâmetro.
⑥ Opcionalmente extender sua variável de ambiente PATH.

3.2.1 Passo 1: Copiar e colar


O primeiro passo é criar um arquivo novo. Abra seu editor de texto favorito e copie
e cole nosso one-liner. Podemos nomear o arquivo de top-words-1.sh (o 1 signi-
fica que esse é o nosso primeiro passo em direção à nossa nova ferramenta de linha
de comando) e coloque-o no diretório ∼/linuxCourse/chapter3, mas você pode
escolher um nome diferente e um caminho diferente também. O conteúdo do arquivo
deve se parecer com algo como abaixo:
curl -s http://www.gutemberg.org/cache/epub/76/pg76.txt |
tr ’[:upper:]’ ’[:lower:]’ | grep -oE ’\w+’ | sort |
uniq -c | sort -nr | head -n 10
Nós estamos usando a extensão .sh para deixar claro que estamos criando um
script shell. No entanto, ferramentas de linha de comando não precisam possuir uma
extensão. De fato, ferramentas de linha de comando raramente possuem extensões.
Aqui está uma pequena dica da linha de comando. Na linha de comando, a sequên-
cia !! é substituída pelo comando que você acabou de rodar. Desta forma, se você
perceber que precisa de privilégios de superusuário para o comando anterior, você
pode rodar sudo !!. Além disso, se você quiser salvar o comando anterior para um
arquivo sem ter que copiá-lo e colá-lo, você pode rodar echo "!!" > scriptname.
Nós podemos agora usar a linha de comando bash para interpretar e executar os
comandos no arquivo.
$> bash ~/book/ch04/top-words-1.sh
6441 and
5082 the
3666 i
3258 a
3022 to
2567 it
2086 t
2044 was
1847 he
1778 of

RASCUNHO
Este primeiro passo já nos economiza a digitação do one-liner na próxima vez que
quisermos usá-lo. Pelo fato de o arquivo não poder ser executado por si só, nós ainda
não podemos falar de uma verdadeira ferramenta de linha de comando. Vamos mudar
isso no próximo passo.
CAPÍTULO 4
POLIMENTO DE DADOS

Raramente os dados obtidos originalmente (dados brutos) encontram-se em um for-


mato ideal para que sejam explorados. É comum ocorrer a falta de dados, inconsistên-
cias, erros, caracteres estranhos ou colunas que não são de interesse. Para uma efetiva
exploração desses dados, é necessário antes fazer um “polimento” neles. Essa fase
inclui as seguintes operações:
• Filtrar linhas.
• Extrair determinadas colunas.

RASCUNHO
• Substituir valores.
• Extrair palavras.
• Lidar com valores omitidos.
• Converter dados de um formato para outro.
Embora muitos concordem que a parte mais interessante de lidar com dados seja
a parte de visualização e modelagem, geralmente uma parte substancial do esforço é
gasta na obtenção e no polimento dos dados.

• Conversão entre formatos de arquivos.


• Aplicação de consultas SQL a arquivos CSV (csvsql).
• Filtragem de linhas (head, tail, sed, awk, grep).
• Extração e substituição de valores (cut, sed, awk, tr).
• União, extração, reordenação de colunas. (processamento: sort, uniq).

Antes de darmos início ao aprendizado de ferramentas úteis no polimento de da-


dos, entretando, vamos à definição de filtros, já que diversas dessas ferramentas podem
assim ser chamadas.

19
4.1 Expressões regulares
Quando rodamos certos comandos no Linux para ler ou editar texto a partir de uma
cadeia de caracteres ou um arquivo, muitas vezes queremos filtrar a saída para uma
determinada seção de interesse. É quando o uso de expressões regulares se faz muito
útil.
Uma expressão regular pode ser definida como uma sequência de caracteres que
representa várias outras sequências de caracteres. Um dos usos mais importantes de
expressões regulares é a possibilidade que elas fornecem de você filtrar a saída de
um comando, de modo a editar apenas as sessões de interesse de um texto ou de um
arquivo.
Expressões regulares são compostas por:

Caracteres ordinários tais como espaço, sublinhado, A-Z, a-z, 0-9.

Metacaracteres que são expandidos para caracteres ordinários, incluindo:

(.) casa com qualquer caractere, exceto uma nova linha.


(*) casa zero ou mais vezes o caractere que o antecede.
[ caracter(es) ] casa com qualquer caractere especificado; também é possível
usar um hífen (-) para indicar um intervalo de caracteres, tais como [a-f],
[1-5] e assim por diante.
^ casa com o início de uma linha.
$ casa com o fim de uma linha.
\ é um caractere de escape.

RASCUNHO
4.2 Filtros
Um filtro é um programa que lê dados a partir da entrada padrão, executa alguma
operação sobre esses dados e escreve o resultado desse processamento na saída padrão.
Essas características simples de um filtro permitem que os dados sejam processados
em poderosos pipelines compostos por diversos filtros, um passando o resultado como
entrada para o próximo filtro. Tais pipelines podem ser usados para reestruturar os
dados para a geração de relatórios úteis, modificar o conteúdo de arquivos além de
realizar diversas tarefas administrativas.
Dito isto, vamos seguir com o aprendizado de alguns ótimos filtros de texto e de
arquivos em Linux.

4.3 Awk
O Awk não é apenas um comando, trata-se de uma poderosa linguagem de programa-
ção que pode ser usada para processamento e busca de padrões em texto. Ele pode ser
usado na construção de filtros muito úteis em Linux.
A sintaxe geral do awk é:

$> awk ’script’ filename


em que ’script’ é um conjunto de comandos entendidos pelo awk e executado no
arquivo (de nome filename no exemplo dado).
Para cada linha do arquivo de entrada, o awk realiza uma cópia da linha e executa
os comandos dados no script nesta cópia.
O ’script’ possui a forma ’/pattern/ action’, em que pattern é uma ex-
pressão regular e a ação action corresponde a o que o awk fará quando o padrão
pattern é encontrado em uma linha.

4.3.1 Expressões regulares


Nesta seção iremos focar nos metacaracteres discutidos acima de acordo com algumas
características do awk.

Exemplo simples
O exemplo abaixo imprime todas as linhas do arquivo /etc/hosts, já que nenhum
padrão é dado:
$> awk ’// {print}’ /etc/hosts
127.0.0.1 localhost
127.0.1.1 asnodeouro

# The following lines are desirable for IPv6 capable hosts


::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes

RASCUNHO
ff02::2 ip6-allrouters

Uso de um padrão
No exemplo a seguir, o padrão localhost é fornecido, de modo que o awk irá casar
com qualquer linha que possua localhost no arquivo /etc/hosts:
$> awk ’/localhost/ {print}’ /etc/hosts
127.0.0.1 localhost
::1 ip6-localhost ip6-loopback
O exemplo a seguir casa strings que possuam um ’t’ seguido de ’p’ ou ’s’.
$> awk ’/t[ps]/ {print}’ /etc/hosts

Uso do padrão coringa ’.’


No exemplo abaixo, o ’.’ irá casar com qualquer caractere único. No caso do padrão
usado, basta que a palavra contenha qualquer caractere único entre um l e um c, tal
como ocorre com “localhost” e “localnet”:
$> awk ’/l.c/ {print}’‘ /etc/hosts
127.0.0.1 localhost
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
Uso do padrão ’*’
A busca pelo padrão l*c no mesmo arquivo que tem sido usado nos outros exem-
plos irá casar com as mesmas palavras anteriores além da linha que contém “lines” e
“capable”, já que o padrão ’*’ casa com qualquer número de caracteres:

$> awk ’/l*c/ {print}’ /etc/hosts

Uso de um conjunto de caracteres


Em determinadas buscas, é necessário que haja o casamento de um conjunto fixo de
caracteres em vez de um número qualquer de qualquer caractere. Nesses casos, deve-
se colocar o conjunto de caracteres desejados entre colchetes: [ e ].

$> awk ’/[al1]/ {print}’ /etc/hosts

4.3.2 Impressão de campos e colunas


4.3.3 Filtragem de texto baseando-se em padrões específicos
4.3.4 Operadores de comparação
4.3.5 Expressões compostas
4.3.6 O comando next
4.3.7 Leitura de entrada padrão

RASCUNHO
4.3.8 Variáveis, expressões numéricas e operadores de atribuição
4.3.9 Os padrões especiais BEGIN e END
4.3.10 Variáveis built-in
4.3.11 Uso de variáveis do shell
4.3.12 Comandos de controle de fluxo
4.3.13 Scripts

4.4 Sed
O comando sed é um poderoso editor de fluxo de dados para filtragem e alteração de
texto. Ele pode ser usado para criar, editar e manipular arquivos em Linux.

4.5 Os comandos grep, egrep, fgrep e rgrep


Estes filtros devolvem linhas que casam com um determinado padrão. Eles lêem linhas
a partir de um arquivo ou da entrada padrão e imprimem na saída padrão todas as
linhas que casam com a sequência de caracteres procurada.
Seguem alguns exemplos de uso do comando grep:
$> grep "pires" /etc/passwd
pires:x:1000:1000:David,,,:/home/pires:/bin/bash

$> cat /etc/passwd | grep "pires"


pires:x:1000:1000:David,,,:/home/pires:/bin/bash
O programa principal é o grep. As variações equivalem ao uso do grep em con-
junto com o uso de algumas opções específicas, tal como mostrado abaixo:
• egrep = grep -E.
• fgrep = grep -F.
• rgrep = -r.

4.6 O comando head


O comando head é usado para mostrar o início de um arquivo: ele exibe as 10 primei-
ras linhas, por padrão. Você pode usar a opção -n para especificar o número de linhas
a serem exibidas:
$> head /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin

RASCUNHO
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin

$> head -n 5 /etc/passwd


root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
O comando head é muito útil, principalmente quando usado em conjunto com os
comandos tail e cat.

4.7 O comando tail


O comando tail exibe a última parte de um arquivo (as 10 últimas linhas por padrão).
Use a opção -n para especificar o número de linhas a serem exibidas.
O comando abaixo exibe as 5 últimas linhas do arquivo especificado:
$> tail -n 5 /var/log/auth.log
Oct 18 07:17:01 asnodeouro CRON[490201]: pam_unix(cron:session): session opened
for user root by (uid=0)
Oct 18 07:17:01 asnodeouro CRON[490200]: pam_unix(cron:session): session closed
for user root
Oct 18 07:17:01 asnodeouro CRON[490201]: pam_unix(cron:session): session closed
for user root
Oct 18 07:25:01 asnodeouro CRON[490781]: pam_unix(cron:session): session opened
for user root by (uid=0)
Oct 18 07:25:01 asnodeouro CRON[490781]: pam_unix(cron:session): session closed
for user root

Adicionalmente, o comando tail possui uma opção especial -f que permite


acompanhar, em tempo real, as alterações que são feitas em um arquivo. Essa ca-
racterística é muito útil para o acompanhamento de arquivos de log. Como exemplo,
o comando seguinte permite que você monitore as mudanças no arquivo especificado:

$> tail -f /var/log/auth.log


Oct 18 08:35:01 asnodeouro CRON[493186]: pam_unix(cron:session): session opened
for user root by (uid=0)
Oct 18 08:35:02 asnodeouro CRON[493186]: pam_unix(cron:session): session closed
for user root
Oct 18 08:45:01 asnodeouro CRON[493529]: pam_unix(cron:session): session opened
for user root by (uid=0)
Oct 18 08:45:01 asnodeouro CRON[493529]: pam_unix(cron:session): session closed
for user root
Oct 18 08:55:01 asnodeouro CRON[493860]: pam_unix(cron:session): session opened

RASCUNHO
for user root by (uid=0)
Oct 18 08:55:01 asnodeouro CRON[493860]: pam_unix(cron:session): session closed
for user root
Oct 18 10:16:23 asnodeouro systemd-logind[1164]: Operation ’sleep’ finished.
Oct 18 10:16:34 asnodeouro kcheckpass[494070]: pam_unix(kde:auth): Couldn’t open
/etc/securetty: No such file or directory
Oct 18 10:16:34 asnodeouro kcheckpass[494359]: pam_unix(kde:auth): Couldn’t open
/etc/securetty: No such file or directory
Oct 18 10:16:34 asnodeouro kcheckpass[494360]: pam_unix(kde:auth): Couldn’t open
/etc/securetty: No such file or directory

4.8 O comando sort


O comando sort é usado para ordenar as linhas de um arquivo ou a partir da entrada
padrão.
Abaixo temos o conteúdo de um arquivo chamado dominios.list:

$> cat dominios.lista


butantan.gov.br
usp.br
butantan.gov.br
ime.usp.br
google.com
ubuntu.com
kubuntu.org
butantan.gov.br
Você pode rodar o comando sort em seu modo mais básico para ordenar o conteúdo
do arquivo, tal como:
$> sort dominios.lista
butantan.gov.br
butantan.gov.br
butantan.gov.br
google.com
ime.usp.br
kubuntu.org
ubuntu.com
usp.br
Há várias formas diferentes de se rodar o comando sort de modo a obter resulta-
dos úteis e interessantes.

4.9 O comando uniq


O comando uniq é usado para relatar ou omitir linhas repetidas consecutivas. Após
rodar o comando sort em um fluxo de dados de entrada, você pode contar o número
de linhas repetidas usando a opção -c do comando uniq, tal qual no exemplo abaixo:

RASCUNHO
$> sort dominios.lista | uniq -c
3 butantan.gov.br
1 google.com
1 ime.usp.br
1 kubuntu.org
1 ubuntu.com
1 usp.br

4.10 O comando fmt


O comando fmt é um formatador simples de texto. Ele reformata os parágrafos em
um arquivo especificado. Exemplos de uso são na formatação de arquivos README e
instruções de instalação escritas em texto puro. Se, por exemplo, um arquivo desses já
está formatado de modo que todas as linhas possuam comprimento similar, é comum
que, ao se editar o meio de uma frase, o parágrafo inteiro deve ser reformatado, de
modo que não sobrem linhas extremamente longas ou outras mais curtas em meio ao
texto. Nesse caso, o comando fmt pode ser usado para deixar todas as linhas com no
máximo 75 colunas, por exemplo.
A formatação realizada pelo fmt não aplica nenhum tipo de estilização do texto,
tais como itálico ou negrito. O comando apenas coleta as palavras e preenche pará-
grafos. Com ele, você pode rapidamente ajustar um texto de modo que ele fique fácil
de ser lido.
A seguir, temos um trecho extraído do livro Os sertões, de Euclides da Cunha:
$> cat trechoOsSertoes.txt
Ao sobrevir das chuvas, a terra, como vimos,
transfigura-se
em
mutações
fantásticas, contrastando com a desolação anterior.
Nesse texto de exemplo, as linhas possuem diferentes comprimentos, com as que-
bras de linha ocorrendo de forma que dificulta a leitura. Esse tipo estranho de dis-
tribuição das palavras em um parágrafo surge geralmente quando realizamos muitas
edições em um arquivo de texto. Para reformatar esse texto, você pode usar o co-
mando fmt de modo a preencher as linhas do parágrafo mantendo um comprimento
uniforme:
$> fmt trechoOsSertoes.txt
Ao sobrevir das chuvas, a terra, como vimos, transfigura-se em mutações
fantásticas, contrastando com a desolação anterior.
Por padrão, o comando fmt formatará o texto em colunas com 75 caracteres de
comprimento, mas você pode alterar esse valor através da opção --width (ou -w):
$> fmt -w 25 trechoOsSertoes.txt
Ao sobrevir das chuvas,
a terra, como vimos,
transfigura-se em
mutações fantásticas,

RASCUNHO
contrastando com a
desolação anterior.
Outras opções que valem a pena serem exploradas:
• --crown-margin (ou -c) para casar a endentação das duas primeiras linhas do
parágrafo, como em uma lista com marcadores.
• --tagged-paragraph (ou -t), para preservar a endentação da primeira linha em
um parágrafo, como geralmente é feito em parágrafos endentados.
• --uniform-spacing (ou -u), para usar um espaço entre palavras e dois espaços
entre frases.

4.11 O comando pr
O comando pr formata a entrada para impressão. Por exemplo, em sistemas Ubuntu
você pode listar todos os pacotes instalados da seguinte forma:
$> dpkg -l
Para organizar a lista em páginas e colunas prontas para serem impressas, execute
o seguinte comando:
$> dpkg -l | pr --columns 3 -l 20
As opções usadas foram:

--column define o número de colunas criadas na saída.

-l especifica o comprimento da página (o padrão são 66 linhas).

4.12 O comando tr
Este comando traduz ou remove caracteres a partir da entrada padrão e escreve o
resultado na saída padrão. A sintaxe para usar o comando tr é a seguinte:

tr opções conjunto1 conjunto2

Observe os exemplos abaixo. No primeiro comando, o conjunto 1 é dado por


[:upper:], representando o conjunto dos caracteres maiúsculos. Já o conjunto 2,
dado por [:lower:], representa o conjunto dos caracteres minúsculos. O que este
comando faz é simplesmente transformar todos os caracteres maiúsculos em caracte-
res minúsculos. O exemplo seguinte faz o contrário.

$> echo "WWW.BUTANTAN.GOV.BR" | tr [:upper:] [:lower:]


www.butantan.gov.br

$> echo "www.butantan.gov.br" | tr [:lower:] [:upper:]


WWW.BUTANTAN.GOV.BR

4.13 O comando more

RASCUNHO
O comando more é um filtro de leitura muito útil, criado basicamente para permitir
a visualização de conteúdo. Ele mostra o conteúdo de um arquivo em um formato
semelhante a uma página, permitindo aos usuários avançar através do pressionamento
da tecla <ENTER> para visualizar mais informação.
Você pode usá-lo para visualizar arquivos grandes, tais como:

$> dmesg | more


[1069344.941874] audit: type=1400 audit(1634413029.443:294): apparmor="DENIED"
operation="mknod" profile="snap.chromium.chromium"
name="/home/pires/snap/chromium/1772/.local/share/.org.chromium.Chromium.b99Rmc"
pid=14167 comm="ThreadPoo
lForeg" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
[1069406.774617] [UFW BLOCK] IN=wlp0s20f3 OUT=
MAC=01:00:5e:00:00:01:30:91:8f:65:20:d2:08:00 SRC=192.168.1.1 DST=224.0.0.1
LEN=36 TOS=0x00 PREC=0xC0 TTL=1 ID=8079 DF PROTO=2
[1069531.804305] [UFW BLOCK] IN=wlp0s20f3 OUT=
MAC=01:00:5e:00:00:01:30:91:8f:65:20:d2:08:00 SRC=192.168.1.1 DST=224.0.0.1
LEN=36 TOS=0x00 PREC=0xC0 TTL=1 ID=8201 DF PROTO=2
[1069574.511932] [UFW BLOCK] IN=wlp0s20f3 OUT=
MAC=5c:cd:5b:48:76:32:30:91:8f:65:20:d2:08:00 SRC=192.168.1.1 DST=192.168.1.11
LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=8247 PROTO=TCP SPT=24720 DPT=8200
WINDOW=4096 RES=0x00 SYN URGP=0
[1069580.339590] [UFW BLOCK] IN=wlp0s20f3 OUT=
MAC=5c:cd:5b:48:76:32:30:91:8f:65:20:d2:08:00 SRC=192.168.1.1 DST=192.168.1.11
LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=8251 PROTO=TCP SPT=24720 DPT=8200
WINDOW=4096 RES=0x00 SYN URGP=0
[1069584.640841] [UFW BLOCK] IN=wlp0s20f3 OUT=
MAC=5c:cd:5b:48:76:32:30:91:8f:65:20:d2:08:00 SRC=192.168.1.1 DST=192.168.1.11
LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=8252 PROTO=TCP SPT=20552 DPT=8200
WINDOW=4096 RES=0x00 SYN URGP=0
[1069590.239329] [UFW BLOCK] IN=wlp0s20f3 OUT=
MAC=5c:cd:5b:48:76:32:30:91:8f:65:20:d2:08:00 SRC=192.168.1.1 DST=192.168.1.11
LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=8262 PROTO=TCP SPT=20552 DPT=8200
WINDOW=4096 RES=0x00 SYN URGP=0
[1069657.141728] [UFW BLOCK] IN=wlp0s20f3 OUT=
MAC=01:00:5e:00:00:01:30:91:8f:65:20:d2:08:00 SRC=192.168.1.1 DST=224.0.0.1
LEN=36 TOS=0x00 PREC=0xC0 TTL=1 ID=8279 DF PROTO=2
[1069781.864030] [UFW BLOCK] IN=wlp0s20f3 OUT=
MAC=01:00:5e:00:00:01:30:91:8f:65:20:d2:08:00 SRC=192.168.1.1 DST=224.0.0.1
LEN=36 TOS=0x00 PREC=0xC0 TTL=1 ID=8309 DF PROTO=2
--More--

4.14 O comando less


O comando less é como se fosse o oposto do comando more visto acima, porém ele
possui mais opções e é um pouco mais rápido com arquivos grandes. Você pode usá-lo
da mesma forma que com o comando more:

RASCUNHO
$> dmesg | less
[1428508.254178] wlp0s20f3: authenticate with 30:91:8f:65:20:d3
[1428508.257440] wlp0s20f3: send auth to 30:91:8f:65:20:d3 (try 1/3)
[1428508.280539] wlp0s20f3: authenticated
[1428508.284081] wlp0s20f3: associate with 30:91:8f:65:20:d3 (try 1/3)
[1428508.288078] wlp0s20f3: RX AssocResp from 30:91:8f:65:20:d3 (capab=0x411
status=0 aid=1)
[1428508.291947] wlp0s20f3: associated
[1428508.459892] IPv6: ADDRCONF(NETDEV_CHANGE): wlp0s20f3: link becomes ready
[1428509.611373] [UFW BLOCK] IN=wlp0s20f3 OUT=
MAC=5c:cd:5b:48:76:32:9c:8c:6e:ca:3c:72:08:00 SRC=192.168.1.2 DST=192.168.1.11
LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=28267 DF PROTO=TCP SPT=41396 DPT=8200
WINDOW=29200 RES=0x00 SYN URGP=0
[1428510.550013] [UFW BLOCK] IN=wlp0s20f3 OUT=
MAC=5c:cd:5b:48:76:32:9c:8c:6e:ca:3c:72:08:00 SRC=192.168.1.2 DST=192.168.1.11
LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=28268 DF PROTO=TCP SPT=41396 DPT=8200
WINDOW=29200 RES=0x00 SYN URGP=0
[1428511.912865] [UFW BLOCK] IN=wlp0s20f3 OUT=
MAC=5c:cd:5b:48:76:32:9c:8c:6e:ca:3c:72:08:00 SRC=192.168.1.2 DST=192.168.1.11
LEN=439 TOS=0x00 PREC=0x00 TTL=64 ID=25116 DF PROTO=UDP SPT=49191 DPT=57506
LEN=419
:
CAPÍTULO 5
EXPLORAÇÃO DE DADOS

Com os dados limpos, pode-se seguir para sua exploração, que consiste em:
• Olhar os dados.
• Calcular estatísticas sobre os dados.
• Criar visualizações.

• Inspeção dos dados e suas propriedades.

RASCUNHO
• Cálculo de estatística descritiva (csvstat, R [mean, sd, sum, summary], Rio).
• Visualização dos dados em modo texto (feedgnuplot).

29
RASCUNHO
Parte II

Organização de pipelines em
Bioinformática: a ferramenta
como unidade

RASCUNHO

31
RASCUNHO
Automatização de tarefas.
O conceito de pipeline.
A ferramenta como unidade do pipeline.

RASCUNHO
RASCUNHO
CAPÍTULO 6
ENTRADA

oda ferramenta atua sobre algum dado que lhe serve de entrada. A ferramenta tool
T apresentada no prefácio não é exceção. Em geral, o nome do arquivo de entrada
é fornecido na própria linha de comando:

$> tool seq.fastq

O ideal é que todos os arquivos que servem de entrada para a ferramenta fiquem
reunidos em um só diretório, chamado input.
Uma opção para ter acesso a todos os arquivos em um só diretório é simplesmente

RASCUNHO
fazer uma cópia dos mesmos. No entanto, ao lembrarmos que a Bioinformática é
um tipo de e-Ciência e, portanto, lida com grandes conjuntos de dados (big data), o
processo de cópia pode levar um tempo considerável e, tão grave quanto, duplicará o
espaço ocupado em disco por esses dados.
A solução é o link simbólico. Um link simbólico é um arquivo que apenas aponta
para outro arquivo. O espaço que ocupa em disco é ínfimo (da ordem de dezenas de
bytes), independente se o link simbólico aponta para um arquivo vazio ou para um
arquivo de vários gigabytes de tamanho. Para criar um link simbólico deve-se usar o
comando ln com a opção -s seguida do caminho do arquivo para o qual se quer criar
o link.

$> ln -s seq.fastq

Link simbólico para evitar replicação de dados.

35
RASCUNHO
CAPÍTULO 7
SAÍDA

a mesma forma que os arquivos de entrada de uma ferramenta são facilmente iden-
D tificados ao serem armazenados todos em um mesmo diretório, os arquivos de
saída, processados pela ferramenta, também o são. A escolha do nome do diretório
não poderia ser mais óbvia: output.

$> mkdir output

Algumas ferramentas possuem uma opção que permite definir o diretório de saída.

RASCUNHO
$> tool --output-dir=output

Para outras, é necessário que você indique um diretório de saída diferente para
cada arquivo de entrada, caso contrário os arquivos serão sobrescritos, já que possuem
o mesmo nome.

$> mkdir output


$> for i in 1 2; do
> mkdir output/${i}
> tool --input=input/${i}.fastq --output-dir=output/${i}
> done

37
RASCUNHO
CAPÍTULO 8
RELATÓRIOS DE EXECUÇÃO

uando uma ferramenta é executada, além de receber arquivos de entrada e produzir


Q arquivos de saída, ela também pode gerar relatórios, informando o andamento
de sua execução. Esses relatórios podem ser de dois tipos:
Saída padrão Também conhecida como saída normal, informa o andamento da exe-
cução, descrevendo os passos que estão sendo executados a cada momento.
Pode também informar a versão da ferramenta e os argumentos que foram pas-
sados para os parâmetros. A saída padrão na linha de comando é a tela, ou
seja, o texto é enviado para exibição no terminal em que o comando está sendo

RASCUNHO
executado. Ela pode ser redirecionada para um arquivo por meio do uso do ope-
rador >, equivalente ao operador 1>. Uma sugestão de extensão para o arquivo
que conterá a saída padrão de um comando é out, mnemônico do inglês output.

$> comando > log/comando.out

Saída de erro Informa erros encontrados durante o processamento e possíveis solu-


ções para que você possa executar a ferramenta com sucesso. A saída de erro
padrão na linha de comando também é a tela. Ela pode ser redirecionada para
um arquivo por meio do uso do operador 2>. É conveniente adotar a extensão
.err para arquivos que contém a saída de erro de programas.

$> comando 2> log/comando.err

Os erros de execução podem ser os mais diversos possíveis, tais como:


Falha de segmentação Ocorre quando um programa tenta acessar uma área da me-
mória que não foi alocada para ele.
Impossibilidade de acessar um arquivo de entrada Ocorre quando um arquivo de
entrada não existe ou quando o programa não possui acesso de leitura ao mesmo.

39
Impossibilidade de escrever um arquivo de saída Ocorre quando o diretório onde
o arquivo de saída deve ser escrito não existe ou quando o programa não possui
acesso de escrita ao mesmo.

Falta de memória Ocorre quando a quantidade de memória existente é insuficiente


para a execução do programa.

8.1 Histórico dos comandos usados


A execução de uma ferramenta geralmente envolve a execução de diversos coman-
dos que vão desde a criação de subdiretórios até o pré-processamento de arquivos,
filtragem, busca por termos, contagem, criação de links simbólicos, cópia de arquivos,
remoção de arquivos, etc. É comum que em um curto espaço de tempo você execute
diversos comandos. Também é comum que em pouco tempo você se esqueça de tudo
o que fez desde o início até chegar ao resultado final. É por esse motivo que você deve
ter o costume de anotar os comandos executados em um arquivo.

8.1.1 O arquivo cmdLine.bash


Padronizemos o nome deste arquivo para cmdLine.bash. O nome é uma abreviação
para “linha de comando” em inglês, usando camel case. A extensão “.bash” não
implica que este arquivo deva ser executado, mas sim enfatiza que todos os comandos
podem ser executados a partir do prompt e ao mesmo tempo permite fazer uso de
syntax highlighting especificamente configurada para Bash nos mais diversos editores
de texto.
Uma forma de se consultar os últimos comandos executados é por meio do co-

RASCUNHO
mando history. Ele imprime na saída padrão uma listagem com todo o histórico dos
últimos comandos executados, um comando por linha.1
No entanto, armazenar o resultado de parte da lista impressa pelo history não é
muito conveniente, não só devido à presença dos números que ordenam os comandos
na primeira coluna, mas também porque essa lista contém todas as suas tentativas
erradas antes de o comando dar certo, além de comandos de verificação do conteúdo
de diretórios ou variáveis, como ls e echo.
O ideal é que você armazene apenas os comandos finais, corretos, além de incluir
comentários sobre o que cada comando faz.

8.1.2 O arquivo COMMANDS


Eventualmente, além do nome da ferramenta usada e dos argumentos que foram usa-
dos para cada parâmetro, você também precisará saber, por necessidade sua ou por ter
sido requisitado por alguém, outras informações, tais como:

• qual foi o usuário que executou a ferramenta;

• em que dia e em que horário a ferramenta foi executada;

• qual foi o servidor usado;


1 Quando se faz uso da tecla “seta para cima” no terminal, percorre-se essa mesma lista de comandos,

do mais recente para o mais antigo.


• qual a versão da ferramenta.

Anotar todas essas informações a cada vez que se usa uma ferramenta é uma tarefa
repetitiva e enfadonha e, justamente por isso, passível de automatização. Juntamente
com este livro é distribuído o script saveCommand.bash. Para usá-lo, basta executá-
lo imediatamente antes da chamada para a ferramenta da qual você deseja registrar as
informações citadas, na mesma linha de comando. As informações serão acrescidas
no diretório de execução, em um arquivo chamado COMMANDS.
Vejamos um exemplo:

$> saveCommand rm file.txt


$> ls
COMMANDS
$> cat COMMANDS
User: pires
Date: Tue Feb 26 16:21:49 -03 2019
Host: lua
Tool: rm
Version: rm (GNU coreutils) 8.28
Command line: rm file.txt

Assim, se quisermos rastrear a remoção do arquivo file.txt, além da versão do


comando rm também saberemos quem, o quê, como, quando e onde (em que máquina)
(a resposta à pergunta “porquê?” é mais complicada e deixo para você explicar isso a
seu chefe/orientador ;-).
Relatórios de execução.

RASCUNHO
• Saída normal.

• Saída de erro.

– Tipos de erro.

Histórico dos comandos usados (versão, parâmetros, data, máquina, usuário).

8.2 Tempo de execução


O tempo de execução de um programa pode ser medido pelo comando builtin time.

$> time comando

No entanto, o comando /usr/bin/time possui mais opções e uma saída mais


amigável. Duas opções interessantes são --verbose, que fornece um relatório mais
completo da execução do comando, e --output, que permite salvar a saída em um
arquivo. Ao usar esta última opção, podemos salvar em arquivos com a extensão time.

$> /usr/bin/time --verbose --output=log/comando.time comando

Dentre as diversas medidas realizadas, alguns campos são mais interessantes que
outros. Vejamos uma saída de exemplo.
Command being timed: "saveCommand ./script/decompressData.bash"
User time (seconds): 1765.36
System time (seconds): 7859.93
Percent of CPU this job got: 235%
Elapsed (wall clock) time (h:mm:ss or m:ss): 1:08:04
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 3464
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 150
Minor (reclaiming a frame) page faults: 172751
Voluntary context switches: 7391684
Involuntary context switches: 270058
Swaps: 0
File system inputs: 68576376
File system outputs: 348777552
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
O uso do comando /usr/bin/time tem como principal objetivo verificar quanto
tempo foi necessário para rodar o comando. Há, porém, diversas medidas de tempo
que são exibidas:

RASCUNHO
User time (seconds): tempo, em segundos, efetivamente usado pelo processo do usuá-
rio.
System time (seconds: tempo usado pelo sistema operacional para gerenciar os pro-
cessos e demais funções de um SO. Uma vez que o Linux é multiusuário e mul-
titarefa, vários processos de vários usuários são executados ao mesmo tempo.
Elapsed (wall clock) time (h:mm:ss or m:ss): tempo de CPU efetivamente usado,
desde o início até o fim do processo. Essa medida é bastante interessante: seu
valor equivale a quanto tempo seria necessário caso o processo tivesse sido
executado em apenas um núcleo do processador. O fato de o processo ter le-
vado efetivamente menos tempo para finalizar está intimamente ligado à me-
dida apresentada no campo Percent of CPU this job got. Quanto maior o valor
dessa porcentagem, maior será a discrepância entre os valores de “Elapsed (wall
clock) time” e “User time”.
Outra medida de grande importância é dada pelo campo Maximum resident set
size (kbytes), que indica o valor máximo de memória RAM que foi necessária durante
a execução do processo. Pode-se tomar como base tanto o tempo de execução quanto
a quantidade máxima de memória para ajustar valores a serem requisitados em um
servidor numa futura execução da mesma ferramenta.
O último campo também tem sua importância: se o valor de saída do comando for
diferente de 0, algo de errado provavelmente ocorreu e deve ser analisado. Neste caso,
certamente vale a pena verificar o relatório da saída de erro armazenado no diretório
log para identificar o que aconteceu de errado.

RASCUNHO
RASCUNHO
CAPÍTULO 9
SCRIPTS E JOBS

om o passar do tempo, fica evidente a necessidade de automatização de determina-


C das tarefas. Isso pode ocorrer devido ao fato de você sempre ter de rodar um
mesmo pipeline com dados diferentes, com os mesmos dados porém com parâmetros
diferentes ou simplesmente porque quer evitar confiar demais em sua memória e cor-
rer o risco de se esquecer de algo. A solução é passar todo o seu conhecimento sobre
como executar as ferramentas, com quais argumentos, em que sequência e usando
quais recursos tudo para scripts.
Scripts são arquivos de texto que são interpretados por um programa (chamado in-

RASCUNHO
terpretador) de modo a serem executados em uma máquina. A diferença de um script
para um programa é que um programa precisa ser compilado para então ser executado.
A compilação traduz o texto do programa em linguagem de máquina. Já a interpreta-
ção ocorre ao mesmo tempo em que o script é executado. Por conta dessa diferença,
programas geralmente possuem uma execução mais rápida que scripts. Exemplos de
linguagens interpretadas: Bash, Python, Perl, Java e R. Exemplos de linguagens com-
piladas: C, C++ e Fortran.
As linguagens de programação mais usadas na área de Bioinformática atualmente1
são R, Python, Perl, Bash e C++. Porém, quando se trata de escrever scripts para fazer
a chamada de outros programas e “conectá-los” fazendo com que a saída de um seja a
entrada de outro, sem dúvida a linguagem mais indicada é o Bash. Programar em Bash
é quase como se você estivesse usando a linha de comando, de modo que os scripts
geralmente são bem simples de serem entendidos. Certamente é possível usar as outras
linguagens para obter o mesmo resultado. No entanto, a sequência de comandos não
será tão direta quanto em Bash e, em algumas delas (e.g., em Python) é preciso usar
funções que simplesmente passam os argumentos para o Bash.
Dito isto, daremos início à escrita de scripts na linguagem Bash, começando pelo
clássico hello world. Usaremos o comando echo para imprimir uma mensagem na
tela.

$> echo "Olá, mundo!"


1 Início de 2019.

45
Execute este comando e você verá que a mensagem “Olá, mundo!” será exibida
na tela. Nosso intuito é escrever um primeiro script que, ao ser executado, realize a
mesma tarefa. Para tanto, devemos inserir a linha de comando acima em um arquivo
de texto. Isso pode ser feito de várias maneiras, como, por exemplo, usando um editor
de texto (kate, vim, nano, joe e emacs são alguns exemplos). No entanto, iremos usar
um comando simples para fazer isso: cat.
O comando cat serve para concatenar dois arquivos (daí o seu nome). Se, por
exemplo, possuímos um arquivo FASTA chamado 1.fasta com o seguinte conteúdo:

> 1
A

e um outro arquivo FASTA chamado 2.fasta com o seguinte conteúdo:

> 2
C

podemos usar o comando cat para concatenar os dois arquivos e obter uma saída
multifasta:

$> cat 1.fasta 2.fasta


> 1
A
> 2
C

ou seja, os arquivos foram concatenados.

RASCUNHO
Existem, porém, outros usos para o comando cat. Um deles é a exibição de um
arquivo na tela:

$> cat 1.fasta

que inclusive pode ser usado para copiar um arquivo:

$> cat 1.fasta > copia1.fasta

Neste último comando usamos o símbolo >, cuja função é redirecionar a saída padrão
para um arquivo. A saída padrão é a tela do computador. O que o símbolo > faz
é enviar o conteúdo que seria exibido na tela para um arquivo, cujo nome vem na
sequência.
Vamos usar estes últimos conceitos aprendidos para gerar nosso primeiro script
Bash.

$> cat > helloWorld.bash

Ao executar o comando acima, você notará que o prompt da linha de comando per-
manece aguardando o fim da entrada de dados, já que o sinal de prompt (que em
nossos exemplos temos usado a sequência de símbolos “$>”) não é exibido. Este é o
momento de entrar com o conteúdo do arquivo. Digite echo "Olá, mundo!" e pres-
sione <ENTER>. A linha de comando continua esperando por entrada, só que agora
em uma nova linha. Como nosso script será composto apenas pelo comando já digi-
tado, podemos finalizar a entrada de dados, o que é feito com a combinação de teclas
<CTRL> + <d>1 .
Desta forma, o arquivo helloWorld.bash foi gerado. Porém, ele não é um ar-
quivo executável, conforme você pode verificar com o comando ls -l ao observar
que não há o caractere x dentre as permissões. Para executar nosso script da forma
como ele está, precisamos passá-lo como entrada para o próprio comando bash:
$> bash helloWorld.bash
Não é muito agradável ter que ficar chamando o bash a todo momento em que se
deseja executar um script em Bash. Para evitar isso, precisaremos fazer duas coisas:
• Indicar no script que o interpretador a ser usado deve ser o comando bash.
• Transformar nosso script em um executável.
A indicação do interpretador do script deve ser feita na primeira linha do mesmo,
a qual deve ser iniciada pelos símbolos “#!” seguidos do caminho absoluto do execu-
tável do interpretador. O conjunto desses dois símbolos é conhecido como shabang2 .
Para descobrir o caminho absoluto do executável do interpretador bash, podemos
fazer uso do comando which.
$> which bash
Na maioria dos sistemas, o executável está em /bin/bash. Portanto, o script com-
pleto passa a ser:
#!/bin/bash

RASCUNHO
echo "Olá, mundo!"
Contudo, não são todos os sistemas que possuem o executável em /bin/bash.
Para evitar que o script não rode nesses sistemas (gerando um erro) e torná-lo mais por-
tável, faremos uso do executável env, que geralmente é instalado em /usr/bin/env.
O papel desta ferramenta é justamente encontrar onde está instalado o programa cujo
nome lhe é passado como argumento e executá-lo. Desta forma, o script portável é:
#!/usr/bin/env bash

echo "Olá, mundo!"


Se quisermos fazer o papel de advogado do diabo, podemos argumentar que a
solução adotada supõe que o executável env esteja instalado em /usr/bin/env, o
que pode não ser verdadeiro para alguns sistemas. Porém, é bem mais provável que
um sistema possua um local alternativo de instalação para o bash do que para o env.
Sendo assim, podemos ficar tranquilos e considerar que este é o script mais portável
que podemos escrever.
1 Você também pode finalizar a entrada de dados ao final de uma linha não vazia, ou seja, sem a ne-

cessidade de teclar <ENTER> antes. Basta pressionar a combinação de teclas <CTRL> + <d> duas vezes
seguidas.
2 sha de sharp, que pode ser traduzido como “sustenido” (em música, um semitom mais agudo que uma

nota natural), e bang como sendo um dos nomes que se dá ao ponto de exclamação em inglês.
Uma outra forma de fornecer a entrada para um arquivo de texto e que particular-
mente considero melhor para a exibição de exemplos é o chamado documento imedi-
ato (do inglês here document).
No documento imediato fazemos uso do operador “«” seguido de uma palavra que
servirá para sinalizar o fim da entrada. Costumo usar a palavra “EOI” (iniciais dos
termos em inglês end of input).
$> cat > helloWorld.bash << EOI
#!/usr/bin/env bash

echo "Olá, mundo!"


EOI

Há um conjunto de boas práticas em programação, com dicas do que se deve


fazer para que seus programas sejam corretos, rápidos, compreensíveis por outros
programadores e, em caso de erros, facilmente corrigíveis. Uma dessas boas práticas
é incluir comentários no código.
Em Bash, comentários são adicionados com o símbolo “#”. Tudo o que vier escrito
após esse símbolo (na mesma linha), será desconsiderado pelo interpretador. Pode se
tratar de apenas uma pequena parte da linha ou a linha por completo.
#!/usr/bin/env bash

# This program says "hello" to the world (in portuguese).

echo "Olá, mundo"! # printing the famous phrase


Note que a primeira linha deste script não pode ser considerada um comentário, já

RASCUNHO que ela não inicia apenas com o símbolo “#” mas sim com o shabang.
Geralmente, logo no início do script, após a linha do shabang, descreve-se, em
forma de comentário, o que o script faz. Essa descrição pode ser tão simples como
no caso acima, com apenas uma frase, como também pode ser composta por várias
linhas, explicando detalhadamente como deve ser cada entrada que é fornecida ao
script, como ele processa esses dados e quais são as saídas produzidas. No caso de o
script ser um pouco mais complexo, pode-se dar preferência a escrever um manual ou
um tutorial no formato PDF, em uma linguagem mais acessível ao usuário final. Ainda
assim, os comentários no código continuam tendo sua importância, porém voltados
para os programadores que eventualmente tenham que lidar com seu código.
É importante frisar que o objetivo de se comentar um código visa o fácil entendi-
mento tanto por outros programadores como por você mesmo. Acredite: nem sempre
se pode confiar na memória. Após alguns dias, é bem capaz que você já tenha esque-
cido de vários detalhes do código e um pequeno comentário lhe poupará muito tempo,
seja para localizar a seção do código que lhe interessa ou para entender o que está
sendo feito e procurar por um eventual erro.
Conversão de one-liners em scripts Bash.
1. A explicação de laços do tipo
for deve vir neste capítulo,
pois são muito usados nos
capítulos seguintes.
CAPÍTULO 10
OUTRAS SEMELHANÇAS

Outras semelhanças.

• config
• final

10.1 Configuração

RASCUNHO
Às vezes necessitamos de configurações específicas para uma determinada execução
de uma ferramenta. Outras vezes, há configurações que são mais persistentes e ra-
ramente são alteradas. Naquelas, geralmente o acerto das configurações é feito via
opções em linha de comando. Nestas, é comum o uso de arquivos que armazenam a
configuração desejada.
Para exemplificar, tomemos a ferramenta Trimmomatic, que é usada para remoção
de adaptadores e filtragem por qualidade. O usuário deve fornecer para o Trimmoma-
tic um arquivo que contenha uma lista de adaptadores a serem removidos das reads
que servem de entrada para o programa. Isso é feito através de uma opção chamada
ILLUMINACLIP. Considerando que o arquivo que armazena a lista de adaptadores
chama-se adapters.fasta, a sintaxe para seu uso é:

$> trimmomatic <...> ILLUMINACLIP:adapters.fasta <...>

Este arquivo pode conter uma lista de centenas de adaptadores. Aqui damos um
exemplo dos nove primeiros adaptadores de uma coleção de 222 no total:

>PrefixPE/1
TACACTCTTTCCCTACACGACGCTCTTCCGATCT
>PrefixPE/2
GTGACTGGAGTTCAGACGTGTGCTCTTCCGATCT
>PE1
TACACTCTTTCCCTACACGACGCTCTTCCGATCT

49
>PE1_rc
AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGTA
>PE2
GTGACTGGAGTTCAGACGTGTGCTCTTCCGATCT
>PE2_rc
AGATCGGAAGAGCACACGTCTGAACTCCAGTCAC
>TruSeqIndexAdapterRightFromDuke
CAATCTCGTATGCCGTCTTCTGCTTG
>TruSeqIndexAdapterRightFromDuke_rc
CAAGCAGAAGACGGCATACGAGATTG
>IlluminaSmallRNAAdapterFromFastQC
ATGGAATTCTCG
...
Certamente é muito mais cômodo armazenar tais adaptadores em um arquivo e
passar apenas o nome do arquivo como argumento para um parâmetro da ferramenta
do que ter de passar todos esses adaptadores na linha de comando.
• Configuração.
• Resultado final.
Estrutura de diretórios.

10.2 Final
O resultado final geralmente é representado por um conjunto de arquivos que é apenas
uma parcela de todos os arquivos gerados durante o processamento. Por vezes, o

RASCUNHO
usuário pode se perder em meio a tantos arquivos ... procurando pelo resultado final.
Para facilitar esta tarefa, podemos criar um diretório chamado final e colocar todos
o resultado final lá. Para evitar a duplicação de dados, podemos apenas fazer links
simbólicos para os arquivos que se encontram no diretório de saída.
$> ln -s ../output/result.txt final/
No caso de vários arquivos de saída representarem o resultado final, podemos usar
um looping for para facilitar a criação de link simbólico para cada um deles, bastando
para isso encontrar um padrão que permita listar todos os arquivos de interesse. Diga-
mos, por exemplo, que o resultado final são todos os arquivos com a extensão fastq
no diretório de saída. Podemos fazer:
$> for i in ‘ls output/*.fastq‘
do
ln -s ../${i} final/
done
Este trecho de código merece algumas observações:
• A cada iteração do looping for, o valor da variável de índice i contém não só o
nome de um arquivo com a extensão fastq no diretório output, mas também o ca-
minho relativo, ou seja, o nome do diretório output. Assim, se o diretório output
possui dois arquivos com a extensão fastq, nomeados 1.fastq e 2.fastq, os
valores que serão tomados por i serão:
output/1.fastq
output/2.fastq

Isso ocorre devido ao uso do caráter coringa * usado no argumento passado para o
comando ls. Se, no entanto, todos os arquivos no diretório output puderem ser
considerados como resultado final, o comando for seria:

$> for i in ‘ls output/‘


do
ln -s ../output/${i} final/
done

Aqui, os valores tomados por i serão:

1.fastq
2.fastq

de modo que se faz necessária a inclusão do nome do diretório output no comando


ln, já que ele não está incluso na variável i.
1. Explicar também o uso no
• Apesar de as variantes de comando for acima serem executadas no diretório que for de apenas output, sem o uso
do ls.
contém (ou seja, é o diretório-pai de) os subdiretórios final e output, ainda assim
2. Acho que essa explicação
há a necessidade de incluir os caracteres ..; é importante entender a razão disso.
talvez deva vir no capítulo de
Observe que estamos usando a sintaxe do comando ln que usa dois parâmetros: “Entrada”, pois lá é a primeira
o caminho do arquivo que será apontado e o caminho do arquivo que constituirá o vez em que links simbólicos são
link simbólico. Sendo assim, devemos lembrar que o local em que será criado o link discutidos. Ou será que lá só

RASCUNHO
simbólico será no subdiretório final, de modo que, para que o subdiretório output fica a explicação de links
seja atingido é preciso primeiro “sair” do diretório final para seu diretório-pai simbólicos com caminhos
para só depois seguir para o subdiretório output. Essa regra vale para qualquer absolutos?
comando ln dado em qualquer lugar do sistema. Uma dica para se lembrar da
inclusão destes ‘..’ é imaginar que se está criando o link simbólico diretamente no
subdiretório final: como seria o caminho até o arquivo que será apontado? Este
será o mesmo caminho a ser usado no comando ln dado fora do diretório.

10.3 Remoção de arquivos


Se for o caso de que os dados de entrada para a ferramenta em questão não serão
usado mais por nenhuma outra ferramenta do pipeline que está sendo executado, este
é o momento de esses dados serem removidos. Porém, muita cautela: a remoção não
é dos links simbólicos no diretório de entrada (eles ocupam um espaço muito pequeno
e indicam qual foi a entrada para a ferramenta) mas sim dos dados para os quais
esses links simbólicos apontam. Isso pode corresponder tanto aos dados armazenados
em data, caso a ferramenta corresponda à ponta de início do pipeline, ou aos dados
resultantes da ferramenta anterior no pipeline.
Perceba que mantemos a constante de que não se mexe nos dados brutos. Tudo o
que está em rawData permanece intacto. O mais próximo que iremos chegar deles é
remover os dados em data, os quais podem ser obtidos novamente por meio da des-
compactação e/ou qualquer outro procedimento anotado no respectivo cmdLine.bash.
Levaremos tempo e gastaremos processamento para obter esses dados novamente, mas
uma vez que se chegue à conclusão de que esses dados não serão mais usados no pi-
peline que se está executando, devemos economizar espaço em disco tão logo seja
possível.
[Pensar se não é o caso de sugerir compactação enquanto o pipeline não for con-
cluído. A remoção seria executada após a publicação, seguida do arquivamento com
backup.]
# Removing decompressed data in order to save space in disk.
rm output/*.fastq

10.4 Visão geral


Nesta parte pudemos identificar diversos padrões que podem ser seguidos indepen-
dente da ferramenta que se está usando.

# Setting up initial directories structure.


mkdir final input log output

Falar sobre o Rclone para compartilhamento de arquivos via Google Drive.

RASCUNHO
Parte III

Organização de pipelines em
Bioinformática: para além da
ferramenta

RASCUNHO

53
RASCUNHO
CAPÍTULO 11
DADOS BRUTOS

Talvez seja interessante já montar um arquivo de metadados no rawData, pois é quando


se tem informações sobre o que foi sequenciado.
Dados brutos (origem (facility, colaborador, universidade, paper), método de se-
quenciamento (illumina, pacbio, orbitrap (se for de espectrometria de massas, arqui-
vos texto)), experimento (identificador único dado pela facility, dados baixados de
outro site, resultados de um pipeline, dados publicados em um artigo, resultantes de
uma tese ou dissertação, se for paper: autorEtAl-ano), {data (planilhas com genes ho-
mólogos em relação ao humano, BED (3 a 12+5) com transcriptoma de novo, GTF,

RASCUNHO
podem ou não estar compactados com gzip, bzip ou zip, checksum MD5, FASTQ
(às vezes os nomes dos arquivos informam metadados, tais como estágio de desen-
volvimento, se é controle ou tratado, o código de barras de identificação, a lane do
sequenciamento, se é R1 ou R2 em um paired-end, além da sequência de concatena-
ção do CASAVA (dá pra montar um exercício: dado o nome de um arquivo em que
se destrincha tudo (FC-S1_GATCAG_L004_R1_010.fastq.gz), que metadados podem
ser esperados a partir de um outro nome de arquivo, com os mesmos campos porém
conteúdo diferente? (MT-S2_ACTTGA_L008_R2_007.fastq.gz)))), doc (emails so-
bre os dados (dizendo o que é cada arquivo e metadados sobre eles) ou com instruções
para download (como servidor FTP, login e senha), comandos (scp) para fazer a có-
pia dos dados a partir de outra rede de computadores, URL a partir da qual os dados
foram baixados, metadados (nome do arquivo, single- ou paired-end, estágio de desen-
volvimento do organismo, droga usada ou metilação de histona (qual?) ou se é input
ou se é controle), planilhas com o sumário do sequenciamento, páginas HTML com
dados do sequenciamento (como lane, sample name, número de bases, Q30%, qua-
lidade média e código de barras), relatórios de BioAnalyzer feitos antes de se enviar
as amostras para sequenciamento, manuais de kits usados para preparar as amostras
}, PDF do paper relacionado aos dados ou então collaborator -> nomeDoColaborador
-> experimento). Se a origem dos dados brutos for de um site (e. g.: Sanger, NCBI,
TriTrypDB), crie os mesmos diretórios seguidos na web.
Texto presente em /work/schisto/rawData/ncbi/nucleotides/cmdLine.bash: To down-
load the file sequence.fasta: go to www.ncbi.nlm.nih.gov, restrict the database to "Nu-

55
cleotide", search for "Schistosoma mansoni [orgn]", click on "Send:", "Complete Re-
cord", choose destination: "File", download 53665 items in format FASTA, sort by
"Default order", show GI active, and finally click "Create File".
Comando executado em /work/schisto/rawData/ncbi/sra/old/SRR2530136/doc: Down-
loading data from NCBI SRA. mv /ncbi/public/sra/SRR2530136.sra data/ /usr/bin/-
nice -n 19 /usr/bin/time –verbose –log=fastq-dump.time saveCommand fastq-dump –
outdir . –split-files –readids –log-level info -v -v -v –ncbi_error_report always SRR2530136
> fastq-dump.out 2> fastq-dump.err
Comando executado em /work/schisto/rawData/ncbi/sra/README-command-lines:
for i in ‘cat files.txt‘; do fastq-dump -Z $i > $i/$i.fastq 2>$i/dump_fastq.err;
done &
cat files.txt
SRR2529486
SRR2529492
SRR2529506
SRR2529484
SRR2529491
SRR2529505
SRR2530112
SRR2530135
SRR2530140
SRR2530111
SRR2530134
SRR2530139
Enfatizar a seguinte sugestão: todos os arquivos e subdiretórios de rawData de-

RASCUNHO
vem ter removida a permissão de escrita, forçando os usuários a mantê-los no formato
original.
CAPÍTULO 12
DADOS

Há uma dicotomia entre o uso de espaço em disco e a velocidade de processamento de


dados. O melhor uso de espaço em disco que você pode fazer é ocupando o mínimo
possível, de modo que é desejável que seus dados sejam compactados. Por outro lado,
a cada vez que você for processar esses dados você terá primeiro que descompactá-los;
e no caso de desejar manter o bom uso de espaço em disco, também terá de compactar
o resultado do processamento.
É aí que está a dicotomia: uso de espaço em disco × velocidade de processamento.
Quanto pior o uso de espaço em disco (maior espaço ocupado), melhor a velocidade

RASCUNHO
de processamento dos dados (execução mais rápida). Inversamente, quanto melhor o
uso de espaço em disco (menor espaço ocupado), pior a velocidade de processamento
dos dados (execução mais lenta). As duas grandezas são inversamente proporcionais.
Uma vez que o espaço em disco é limitado e ninguém quer ficar esperando uma eterni-
dade pela execução de um programa, é esperado um bom balanceamento dessas duas
grandezas por parte do bioinformata.
Há duas soluções que podem ser empregadas nesse caso:
① gzip de -0 a -9.
② descompactar tudo, processar tudo, compactar tudo.
Às vezes os dados brutos não precisam passar por nenhum pré-processamento:
já estão prontos para iniciar o devido pipeline. Ainda nestes casos, fazemos uma
referência a eles no diretório data, usando links simbólicos não apenas para arquivos
mas inclusive para diretórios inteiros em alguns casos. Se não haverá processamento,
o output será link simbólico para input. Mas então já vale a pena fazer, direto, um link
simbólico para final. Ou vale a pena ser mais radical e fazer apenas um link simbólico
para o final, sem input? Daria para fazer isso em todos os casos?

12.1 Links simbólicos


No diretório de dados, fazemos links simbólicos para os dados brutos em rawData. O
intuito do link simbólico em vez de cópia é economizar espaço em disco. Para fazer

57
os vários links simbólicos, geralmente usamos um for. Explicar a diferença de um “ls
diretorio” para um “ls diretorio/*” ao usar o comando para fazer links simbólicos.
Nem tudo o que está presente em rawData deve ter link simbólico em data. Os
dados necessários para processamento, geralmente, são os FASTQ e MD5 check sum.
No caso de os dados brutos consistirem de uma quantidade enorme de arquivos
por biblioteca, com cada biblioteca correspondendo a um diretório, deve-se avaliar
a possibilidade de fazer um link simbólico diretamente para cada diretório. É o que
ocorre com facilities que usam o programa CASAVA, da Illumina, para dividir cada
arquivo FASTQ de cada biblioteca em vários outros arquivos menores (em torno de
25). O intuito de se fazer essa divisão é evitar a transmissão de arquivos enormes
pela rede, o que pode ser muito propenso a erros. Assim, caso haja algum erro na
transmissão de algum arquivo, a quantidade de dados a serem retransmitidos é bem
menor. Exemplo: um arquivo de 25 GB dividido em 25 arquivos de 1 GB.

AD-S1_ATCACG_L004_R1_001.fastq.gz AD-S1_ATCACG_L004_R1_010.fastq.gz AD-S1_ATCACG_L0


AD-S1_ATCACG_L004_R1_002.fastq.gz AD-S1_ATCACG_L004_R1_011.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_003.fastq.gz AD-S1_ATCACG_L004_R1_012.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_004.fastq.gz AD-S1_ATCACG_L004_R1_013.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_005.fastq.gz AD-S1_ATCACG_L004_R1_014.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_006.fastq.gz AD-S1_ATCACG_L004_R1_015.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_007.fastq.gz AD-S1_ATCACG_L004_R1_016.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_008.fastq.gz AD-S1_ATCACG_L004_R1_017.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_009.fastq.gz AD-S1_ATCACG_L004_R1_018.fastq.gz AD-S1_ATCACG_L0

Como geralmente os links simbólicos gerados no diretório data referem-se a ar-


quivos que encontram-se no diretório rawData, os caminhos usados para os arquivos
são absolutos.

RASCUNHO
$> for i in ‘ls /work/schisto/rawData/duke/illumina/id2481/data/*‘
do
ln -s ${i} input/
done

Note que o uso do caráter * no comando ls quando este gera a lista de um looping
for é bastante útil no caso de caminhos absolutos para arquivos.

12.1.1 Cuidados a serem tomados com links simbólicos


Comentar sobre dois casos interessantes que podem surgir ao se lidar com links sim-
bólicos:

Quebra de link. Quando se remove um arquivo para o qual existem links simbólicos,
esses links ficam quebrados. Descobrir os links quebrados com o comando:

$> find . -follow -type l

Exemplo: um colaborador fornece dados de anotação que são colocados em


.../rawData/collaborator/joazinho/. Posteriormente, quando já foram
feitos links simbólicos para os arquivos neste diretório, o colaborador fornece
os scripts que usou para fazer a anotação anteriormente fornecida. Para uma
melhor organização, decide-se mover a anotação para um subdiretório chamado
annotation e os scripts para um subdiretório irmão deste último, chamado
annotationScripts. Ao se mover os arquivos de anotação, todos os links
simbólicos que apontavam para eles ficarão quebrados. Deve-se encontrá-los,
refazê-los e corrigir o comando que eventualmente foi armazenado no respec-
tivo cmdLine.bash.
Alteração de conteúdo. Os exemplos de links simbólicos fornecidos visam o uso dos
arquivos apontados como entrada para programas que irão lê-los, apenas lê-los.
Deve-se ficar muito atento ao processsamento que é feito, de modo a garantir
que tais arquivos não serão modificados. Isso porque pode-se, sem querer e
indiretamente, alterar o conteúdo de arquivos que representam dados brutos e
que, por padrão, deveriam permanecer no estado original. Este quesito pode
ser forçado simplesmente ao se seguir a sugestão de remoção da permissão de
escrita em todos os arquivos que ficam armazenados em rawData.

12.2 MD5 check sum


Para checar a integridade dos dados baixados, podemos usar o md5 ou o sha. Se a
facility usou o MD5, ela provavelmente criou um arquivo com o comando md5 -...
. Este arquivo possui duas colunas separadas por um caráter <TAB>. Na primeira
coluna temos um código MD5, na segunda o nome do arquivo que gerou este código.
O número de linhas corresponde ao número de arquivos para os quais foi gerado o
código.
<código 1> <TAB> <arquivo1> <código 2> <TAB> <arquivo2>

RASCUNHO
Exemplo:
6f7768245a2b2846a0157768b8dfed46 /nfs/seqcore/dataDelivery/Data/Illumina/150625A4/ProjectVERJOSKI-
ALMEIDA2385150625A4/SampleAD-S2/SampleSheet.csv 7f446e7b5fe1948e0c093080b75532dc
/nfs/seqcore/dataDelivery/Data/Illumina/150625A4/ProjectVERJOSKI-ALMEIDA2385150625A4/SampleAD-
S2/AD-S2CGATGTL004R2001.fastq.gz 72420179c1c5c89e62f926ac159bd7b0 /nfs/seqcore/dataDelivery/Data/Illumina/150
ALMEIDA2385150625A4/SampleAD-S2/AD-S2CGATGTL004R2002.fastq.gz fe664c3a46971c949241668d8f69d18f
/nfs/seqcore/dataDelivery/Data/Illumina/150625A4/ProjectVERJOSKI-ALMEIDA2385150625A4/SampleAD-
S2/AD-S2CGATGTL004R1002.fastq.gz 366aec01f625788a01204ff37e2ed758 /nfs/seqcore/dataDelivery/Data/Illumina/150
ALMEIDA2385150625A4/SampleAD-S2/AD-S2CGATGTL004R2003.fastq.gz
Note, porém, que o caminho indicado para o arquivo corresponde ao que se encon-
tra na máquina da facility. Para que você possa usá-lo, é preciso fazer uma substituição
com o comando sed e trocar para o caminho no servidor em que você está trabalhando.
Como o caráter ’/’ aparece como divisor de diretórios no caminho dos arquivos,
precisamos usar um outro caráter na sintaxe de substituição do comando sed. Usemos
o ’|’.
sed -e
’s|/nfs/seqcore/dataDelivery/Data/Illumina/150625A4|/work/schisto/rawData/duke/
illumina/verjovski-almeida_2385|’ input/checksum_2385.txt >
output/checksum_2385-fixedPath.txt

# Verifying if all data was correctly downloaded.


nohup nice -n 19 time savecommand md5sum --warn --check --strict
output/checksum_2385-correctedPath.txt > log/md5sum.out 2> log/md5sum.err &
grep -c ’OK$’ log/md5sum.out 2> log/grep.err | tee log/grep.out
find input/Sample_*/* | wc -l 2> log/find.err | tee log/find.out
Como gerar o arquivo (igual feito na facility?). Explicar a verificação visual e
incentivar a verificação automática.
# Checking if the number of bases and reads are the same informed by Duke facility.
nohup nice -n 19 time saveCommand dukeStats
/work/schisto/rawData/duke/illumina/verjovski-almeida_2385/Project_VERJOSKI-
ALMEIDA_2385_150625A4/ > log/dukeStats.out 2> log/dukeStats.err &
savecommand dukeReport
/work/schisto/rawData/duke/illumina/verjovski-almeida_2385/Project_VERJOSKI-
ALMEIDA_2385_150625A4/ > log/dukeReport.err 2> log/dukeReport.out
Às vezes, a facility separa arquivos do tipo FASTQ grandes em vários arquivos
menores, usando um programa da Illumina chamado CASAVA. Desta forma, cada
arquivo menor possui uma menor probabilidade de ser baixado com erro. Veja uma
exemplo.
AD-S1_ATCACG_L004_R1_001.fastq.gz AD-S1_ATCACG_L004_R1_010.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_002.fastq.gz AD-S1_ATCACG_L004_R1_011.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_003.fastq.gz AD-S1_ATCACG_L004_R1_012.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_004.fastq.gz AD-S1_ATCACG_L004_R1_013.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_005.fastq.gz AD-S1_ATCACG_L004_R1_014.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_006.fastq.gz AD-S1_ATCACG_L004_R1_015.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_007.fastq.gz AD-S1_ATCACG_L004_R1_016.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_008.fastq.gz AD-S1_ATCACG_L004_R1_017.fastq.gz AD-S1_ATCACG_L0
AD-S1_ATCACG_L004_R1_009.fastq.gz AD-S1_ATCACG_L004_R1_018.fastq.gz AD-S1_ATCACG_L0

RASCUNHO
No entanto, para realizar o processamento desses dados, é razoável que aqueles
referentes a uma mesma amostra estejam concatenados em um só arquivo. Podemos
fazer essa concatenação concomitantemente à descompactação de cada arquivo.
#!/bin/bash

# concatenateData.bash

for i in ‘ls -dv input/Sample_*‘; do


# The -c option of gunzip send the uncompressed file to standard output.
gunzip -c $i/*_R1_*.gz > output/‘basename $i‘_R1.fastq &
gunzip -c $i/*_R2_*.gz > output/‘basename $i‘_R2.fastq &
done
wait

exit 0
A opção -c do gunzip envia o arquivo descompactado para a saída padrão. Obser-
var a beleza existente na capacidade de concatenação de arquivos compactados com
o gzip, oferecendo uma outra solução: primeiro concatenar todos os arquivos (será
que precisa garantir que eles foram concatenados com o mesmo nível de compacta-
ção, indicado por -1 a -9?) e depois descompactar o arquivo concatenado (talvez esse
exemplo deva vir antes do já descrito).
12.3 Descompactação de dados
Ao usar o comando unzip em sua forma padrão, ou seja, sem o uso de nenhuma de
suas opções, os dados serão descompactados no local de origem: o diretório rawData,
o que queremos evitar. Para que os dados sejam descompactados no subdiretório
output, devemos fazer uso da opção -d.

$> unzip input/file.fastq.zip -d output/

Ao final, podemos gerar os links simbólicos para o resultado final.

# Making symbolic links for the final result.


for i in ‘ls output/*.fastq‘
do
ln -s ../${i} final/
done

Estudar a diferença entre usar ou não o ’ls’ na listagem do for.

12.4 Checagem: número de reads e de nucleotídeos


Algumas facilities fornecem, junto com os arquivos FASTQ resultantes do sequenci-
amento, uma página na web informando o número de reads e de nucleotídeos obtidos
para cada amostra.
Após a descompactação dos arquivos, é possível fazer a contagem e comparar com
a informação dada pela facility.

RASCUNHO
Exemplo de script para calcular a estatística dos arquivos de entrada (dukeS-
tats.bash):

#!/bin/bash

# Usage example: dukeStats


/work/schisto/data/duke/gsk343/verjovski_almeida_2385/Project_VERJOVSKI-
ALMEIDA_2385_150625A4/

PROJECT=$1

echo "Analising files of $PROJECT:"

# Uncomment below if the project has a subdirectory for each sample.


# for i in ‘ls -v $PROJECT‘; do
# echo " Analising files of $i:"
# for j in ‘find $PROJECT$i -name "*.gz" | sort‘; do
# COUNT_SEQS=‘count_seqs $j‘
# NUM_READS=‘echo $COUNT_SEQS | cut -d’ ’ -f1‘
# NUM_BASES=‘echo $COUNT_SEQS | cut -d’ ’ -f2‘
# echo " $j: $NUM_BASES bases in $NUM_READS reads"
# done
# done
# Uncomment below if the project is composed only by files.
for j in ‘find $PROJECT -name "*.gz" | sort‘; do
COUNT_SEQS=‘count_seqs $j‘
NUM_READS=‘echo $COUNT_SEQS | cut -d’ ’ -f1‘
NUM_BASES=‘echo $COUNT_SEQS | cut -d’ ’ -f2‘
echo " $j: $NUM_BASES bases in $NUM_READS reads"
done

exit 0

Exemplo de sumário das estatísticas calculadas acima (dukeReport.bash):

#!/bin/bash

PROJECT=$1

TOTAL_SUM=0
TOTAL_READS=0

# Work for GSK343.


# echo -e "\"Sample name\"\t\"Base Pairs\"\t\"Reads\"\t\"Barcode\""
#
# for i in ‘ls -v $PROJECT | grep -v checksum‘
# do
# let SUM=0;

RASCUNHO
# let READS=0;
# IFS=’
# ’
# for j in ‘grep $i log/dukeStats.out | grep work‘
# do
# PORTION=‘echo $j | cut -d’ ’ -f6‘
# let "SUM = $SUM + $PORTION"
# PORTION=‘echo $j | cut -d’ ’ -f9‘
# let "READS = $READS + $PORTION"
# done
# let "SUM = $SUM / 2"
# let "READS = $READS / 2"
# BARCODE=‘echo $j | cut -d’/’ -f10 | cut -d’_’ -f2‘
# echo -e "$i\t$SUM\t$READS\t$BARCODE"
# let "TOTAL_SUM = $TOTAL_SUM + SUM"
# let "TOTAL_READS = $TOTAL_READS + READS"
# done

# Work for TB7-36 and tryCru.


echo -e "\"Sample name\"\t\"Base Pairs\"\t\"Reads\""

for i in ‘ls -v $PROJECT | grep -v checksum | grep -v README | cut -d’_’ -f1-3 | uniq
do
let SUM=0;
let READS=0;
IFS=’

for j in ‘grep $i log/dukeStats.out‘
do
PORTION=‘echo $j | cut -d’ ’ -f6‘
let "SUM = $SUM + $PORTION"
PORTION=‘echo $j | cut -d’ ’ -f9‘
let "READS = $READS + $PORTION"
done
# let "SUM = $SUM / 2"
let "READS = $READS / 2"
echo -e "$i\t$SUM\t$READS"
let "TOTAL_SUM = $TOTAL_SUM + SUM"
let "TOTAL_READS = $TOTAL_READS + READS"
done

echo -e "TOTAL\t$TOTAL_SUM\t$TOTAL_READS"

exit 0
Exemplo de saída do programa dukeReport.bash:
"Sample name" "Base Pairs" "Reads" "Barcode"
Sample_TH-S1 16052069754 127397379 GTGGCC
Sample_TH-S2 9038371482 71733107 ATTCCT

RASCUNHO
Sample_TH-S3 1244991888 9880888 TTAGGC
Sample_TH-S4 1410961608 11198108 TGACCA
Sample_TH-S5 1326715488 10529488 ACAGTG
Sample_TH-S6 1743477750 13837125 GCCAAT
Sample_TH-S7 1392361614 11050489 CAGATC
Sample_TH-S8 1405446084 11154334 ACTTGA
Sample_TH-S9 1708589736 13560236 GATCAG
Sample_TH-S10 1332926154 10578779 TAGCTT
Sample_TH-S11 1226760444 9736194 GGCTAC
Sample_TH-S12 1382041332 10968582 CTTGTA
Sample_TH-S13 1489233312 11819312 AGTCAA
Sample_TH-S14 1476191304 11715804 AGTTCC
Sample_TH-S15 1511529894 11996269 ATGTCA
Sample_TH-S16 1443095388 11453138 CCGTCC
Sample_TH-S17 1448208342 11493717 GTCCGC
Sample_TH-S18 1941605316 15409566 GTGAAA
Sample_TH-S19 1512360234 12002859 GTGGCC
Sample_TH-S20 1713482442 13599067 GTTTCG
Sample_TH-S21 1590529122 12623247 CGTACG
Sample_TH-S22 1342001178 10650803 GAGTGG
Sample_TH-S23 1524197682 12096807 ACTGAT
Sample_TH-S24 1532872656 12165656 ATTCCT
TOTAL 57790020204 458650954
12.5 Remoção dos dados
Esta seção final retoma a discussão do início do capítulo, sobre a dicotomia existente
entre o uso de espaço em disco × velocidade de processamento.
Note que a diferença de conteúdo entre o diretório que armazena os dados e o que
armazena os dados brutos é apenas a descompactação destes e, eventualmente, uma
reorganização obtida por meio da concatenação de alguns arquivos. Isso significa que
o diretório de dados possui um potencial de uso de espaço em disco ainda maior que o
diretório de dados brutos. Não é exagero, portanto, manter o compromisso de remover
esses dados tão logo quanto possível.
A remoção pode ser feita com segurança, uma vez que os dados podem ser obti-
dos novamente a partir dos dados brutos, seguindo todas as instruções armazenadas
no arquivo cmdLine.bash. O custo é o tempo de processamento necessário para a
descompactação e eventual concatenação.
O desafio é decidir o momento em que a remoção deve ser feita. Conforme discu-
tido na Seção 10.3, este momento é definido quando todas as ferramentas que fazem
parte da fase inicial do pipeline do projeto sendo executado já tiverem finalizado seu
processamento. Há, aqui, três pontos a serem observados:

• Logo na primeira fase de um pipeline pode ser que haja uma ou mais bifurcações
no fluxo de dados, implicando que esses dados serão usados, nos primeiros passos
do pipeline, por mais de uma ferramenta.
• Em alguns casos ocorre que uma mesma biblioteca é usada como controle para
vários outros experimentos. Assim, o fato de já se ter executado a primeira parte de
um pipeline para um experimento pode implicar que alguns arquivos já podem ser
removidos da pasta de dados, mas deve-se ter o cuidado de verificar se nenhuma das

RASCUNHO
amostras controle também será usada como controle para algum outro experimento
ainda a ser processado.
• Em alguns pipelines, as primeiras rodadas de algumas ferramentas servem apenas
para determinar os melhores parâmetros a serem usados por outras ferramentas, as
quais serão usadas para processar os dados originais. Não remove os arquivos do
diretório dados enquanto não passar por esta fase em um pipeline.
CAPÍTULO 13
METADADOS

1. Incluir discussão sobre a


ma vez que os metadados estejam preparados e o link simbólico criado no diretório inclusão dos sufixos _R1 e _R2
U em que se organizará o pipeline, iremos fazer referência a esse link a partir do em paired-end reads. Como
script de execução de cada ferramenta. ambos os arquivos referem-se a
Consideremos que no meio do pipeline haverá um passo de mapeamento, o qual uma mesma amostra, não faz
se chamará 03-mapping e para o qual será criado um diretório com esse mesmo sentido atribuir um
nome, “vizinho” do link simbólico para o diretório dos metadados do experimento identificador único a cada um.
em questão1 . Dentro deste diretório haverá subdiretórios que armazenarão os arqui- É melhor manter o
vos referentes a diferentes ferramentas de mapeamento. Tomemos como exemplo o identificador único para a

RASCUNHO
mapeador STAR. amostra e usar esses sufixos.
Conforme discutido no Capítulo 9, o script para o mapeador STAR
Sempre que criamos um link simbólico, temos a oportunidade de alterar o nome
do link para algo que seja mais significativo. O melhor momento para se fazer isso
é quando se tem os metadados do experimento, indicando detalhes que podem ser
usados na renomeação.

13.1 Metadados nos nomes dos arquivos


É possível que a facility usada para o sequenciamento faça uso de informações passa-
das junto às amostras enviadas para a nomeação dos arquivos gerados. Desta forma,
os nomes dos arquivos passam a incluir metadados que facilitam a identificação deles
com as amostras sequenciadas. Vejamos alguns exemplos:

AD-S1_ATCACG_L004_R1_001.fastq.gz
AD-S1_ATCACG_L004_R2_026.fastq.gz
FC-S2_ACTTGA_L004_R1_019.fastq.gz
FT-S3_CTTGTA_L004_R2_015.fastq.gz

Nos exemplos podemos extrair os seguintes metadados:


1 Ou seja, ambos possuem o mesmo diretório pai.

65
Organismo Os arquivos iniciados com SM foram obtidos a partir de material extraído
de Schistosoma mansoni e os iniciados com TC a partir de Trypanosoma cruzi.
Número da amostra A numeração de amostras é importante para diferenciar entre
réplicas biológicas ou até mesmo entre materiais pertencentes a experimentos
diferentes, como por exemplo controle vs tratado, macho vs fêmea, concen-
tração de fármaco, tempo de exposição (à fármaco, radiação, etc.), estágio de
desenvolvimento (adulto, epimastigota, esquistossômulo), etc.
Código de barras Serve para identificação da amostra dentre as várias que foram
sequenciadas na mesma lane do sequenciador. Geralmente é removida dos reads
antes de ser gerado o FASTQ final.

Identificador da lane O sequenciamento pode ser feito em lanes diferentes basica-


mente por dois motivos:
Réplica técnica Além das réplicas biológicas, que garantem força estatística
para as conclusões das análises em meio a materiais obtidos de diferentes
organismos (o que mais pode ser diferente?), também pode-se criar ré-
plicas técnicas, que permitem a identificação do chamado efeito de lote,
que pode ser produzido por diferenças entre reagentes e demais substân-
cias usadas em bancada ou durante o sequenciamento. O sequenciamento
em lanes diferentes é uma forma de garantir que não houve interferência
causada pelos materiais usados durante o sequenciamento.
Excesso de material biológico Às vezes, o material biológico enviado para se-
quenciamento possui volume que ultrapassa o limite máximo suportado
por uma lane. Nesses casos, uma mesma réplica biológica pode ser se-

RASCUNHO
quenciada em mais de uma lane e os arquivos resultantes por lane podem
ser concatenados, de modo a serem processados como representantes de
uma única amostra.
CAPÍTULO 14
PROGRAMAS E PIPELINES

Programas e pipelines.

• local
• prog

• pipeline

RASCUNHO

67
RASCUNHO
CAPÍTULO 15
HUBS

RASCUNHO

69
RASCUNHO
CAPÍTULO 16
DADOS DE REFERÊNCIA

RASCUNHO

71
RASCUNHO
CAPÍTULO 17
OUTROS DIRETÓRIOS ÚTEIS

Outros diretórios úteis.

• users (dados do usuário).


• www

17.1 WWW

RASCUNHO
É importante compartilhar com seus colaboradores os arquivos de metadados, já que
são eles que fazem a ligação entre os dados brutos e o significado de cada arquivo.
Sendo assim, deve-se copiar os arquivos samples.txt e experiment.txt para a
página web do projeto.

73
RASCUNHO
Parte IV

Casos de uso

RASCUNHO

75
RASCUNHO
CAPÍTULO 18
FORMATOS DE ARQUIVOS

18.1 CSV e TSV

18.2 FASTA
Ler: https://www.biostars.org/p/144950/.
O formato de arquivos FASTA é um arquivo de texto (em oposição a um arquivo
binário) usado tanto para representar uma sequência de nucleotídeos quanto de ami-

RASCUNHO
noácidos por meio de um caractere para cada um. Com o fim de identificação, do-
cumentação e inclusão de metadados, também é possível preceder a sequência com
nomes, números e comentários.
Sua origem deu-se com um pacote de programas homônimo, usado para fazer a
busca de sequências de proteínas. O fato de o formato ser um arquivo de texto permite
sua leitura por humanos, além de seu fácil processamento por meio de ferramentas
de processamento de texto e por linguagens de programação e de script, tais como C,
Bash, Python e R. Também implica que sua taxa de compactação costuma ser bem
alta.

18.2.1 Formato
Um arquivo FASTA pode ser dividido em duas partes:

Cabeçalho: É composto por uma única linha e inicia-se com o caractere ‘>’ (maior
que). A presença deste símbolo é a única obrigatoriedade do padrão no que con-
cerne à linha de cabeçalho. No entanto, é comum que também sejam incluídos
um identificador da sequência e alguns metadados com uma descrição sobre a
sequência. Caso esteja presente, o identificador deve iniciar-se imediatamente
após o símbolo ‘>’, com seu primeiro caractere na segunda coluna. Geralmente,
o identificador da sequência e os metadados são separados por um caractere de
espaço, de modo que o identificador costuma ser a primeira palavra após o sinal
‘>’.

77
Sequência: Pode ser composta por uma ou mais linhas de sequências de caracteres
representando nucleotídeos ou aminoácidos. Não há uma regra determinando o
número de caracteres por linha, nem mesmo a exigência de que esse número seja
o mesmo para cada linha. Por razões históricas, como os monitores antigos,
1. Para organizar arquivos de
texto com um mesmo número de
que só exibiam texto, suportavam apenas 80 colunas, geralmente as linhas de
caracteres por coluna, dê uma um arquivo FASTA possuem no máximo 80 caracteres (60 também é bastante
olhada no comando fold. comum). Também é comum que todas as linhas possuam o mesmo compri-
mento, já que não há razão para a variação, exceção feita à última linha, já que
o comprimento da sequência não necessariamente será um múltiplo do número
de caracteres usado por linha. No caso da certeza de que o arquivo será lido
somente por computadores, é comum manter toda a sequência em apenas uma
linha, economizando assim o espaço em disco ocupado pelo caráter ‘\n’, que
indica o início de uma nova linha.
Um exemplo mínimo de conteúdo de um arquivo no formato FASTA é:
>
A
Neste exemplo, não há um identificador nem uma descrição para a sequência, a qual
é composta apenas pelo caráter ‘A’, que pode ser uma adenina ou uma alanina, de-
pendendo se o arquivo
R Q representa uma sequência de nucleotídeos ou de aminoácidos,
respectivamente. cos 2
O exemplo abaixo é mais útil: representa a sequência de aminoácidos da proteína
Spike do coronavírus SARS-Cov-2, causador da COVID-19.
>sp|P0DTC2|SPIKE_SARS2 Spike glycoprotein OS=SARS Coronavirus 2
MFVFLVLLPLVSSQCVNLTTRTQLPPAYTNSFTRGVYYPDKVFRSSVLHSTQDLFLPFFS

RASCUNHO
NVTWFHAIHVSGTNGTKRFDNPVLPFNDGVYFASTEKSNIIRGWIFGTTLDSKTQSLLIV
NNATNVVIKVCEFQFCNDPFLGVYYHKNNKSWMESEFRVYSSANNCTFEYVSQPFLMDLE
GKQGNFKNLREFVFKNIDGYFKIYSKHTPINLVRDLPQGFSALEPLVDLPIGINITRFQT
LLALHRSYLTPGDSSSGWTAGAAAYYVGYLQPRTFLLKYNENGTITDAVDCALDPLSETK
CTLKSFTVEKGIYQTSNFRVQPTESIVRFPNITNLCPFGEVFNATRFASVYAWNRKRISN
CVADYSVLYNSASFSTFKCYGVSPTKLNDLCFTNVYADSFVIRGDEVRQIAPGQTGKIAD
YNYKLPDDFTGCVIAWNSNNLDSKVGGNYNYLYRLFRKSNLKPFERDISTEIYQAGSTPC
NGVEGFNCYFPLQSYGFQPTNGVGYQPYRVVVLSFELLHAPATVCGPKKSTNLVKNKCVN
FNFNGLTGTGVLTESNKKFLPFQQFGRDIADTTDAVRDPQTLEILDITPCSFGGVSVITP
GTNTSNQVAVLYQDVNCTEVPVAIHADQLTPTWRVYSTGSNVFQTRAGCLIGAEHVNNSY
ECDIPIGAGICASYQTQTNSPRRARSVASQSIIAYTMSLGAENSVAYSNNSIAIPTNFTI
SVTTEILPVSMTKTSVDCTMYICGDSTECSNLLLQYGSFCTQLNRALTGIAVEQDKNTQE
VFAQVKQIYKTPPIKDFGGFNFSQILPDPSKPSKRSFIEDLLFNKVTLADAGFIKQYGDC
LGDIAARDLICAQKFNGLTVLPPLLTDEMIAQYTSALLAGTITSGWTFGAGAALQIPFAM
QMAYRFNGIGVTQNVLYENQKLIANQFNSAIGKIQDSLSSTASALGKLQDVVNQNAQALN
TLVKQLSSNFGAISSVLNDILSRLDKVEAEVQIDRLITGRLQSLQTYVTQQLIRAAEIRA
SANLAATKMSECVLGQSKRVDFCGKGYHLMSFPQSAPHGVVFLHVTYVPAQEKNFTTAPA
ICHDGKAHFPREGVFVSNGTHWFVTQRNFYEPQIITTDNTFVSGNCDVVIGIVNNTVYDP
LQPELDSFKEELDKYFKNHTSPDVDLGDISGINASVVNIQKEIDRLNEVAKNLNESLIDL
QELGKYEQYIKWPWYIWLGFIAGLIAIVMVTIMLCCMTSCCSCLKGCCSCGSCCKFDEDD
SEPVLKGVKLHYT
Diferentes extensões usadas: fasta, fa, faa.
Indexação: extensão fai (samtools, bowtie, tophat).
Maiúsculas e minúsculas para mascaramento (regiões repetitivas).
Pacote seqkit.
Presença de Ns.
Cabeçalho.
Exercício: descubra se o fasta é de nucleotídeo ou aminoácido. Dá pra afirmar
com certeza?

18.2.2 Arquivos multifasta


O sequenciamento de larga escala usado atualmente é capaz de gerar milhões de
sequências em uma única corrida. Em vez de serem gerados milhões de arquivos
FASTA, cada um contendo uma sequência, o usual é gerar apenas um arquivo com
todas as sequências em formato FASTA, uma seguida da outra. Dizemos que estes são
arquivos multifasta.
Em um arquivo multifasta, uma sequência termina quando o arquivo termina ou
quando é encontrado o símbolo ‘>’ no início de uma linha, que indica o início de uma
outra sequência.
O exemplo de conteúdo de um arquivo multifasta abaixo exibe as três possibilida-
des de códons de parada no DNA.

>amber
TAG
>ochre
TAA
>opal
TGA

RASCUNHO
18.2.3 Códigos usados nas sequências
Número de nucleotídeos por linha, características comuns na linha de identificação
(ID, comprimento, número de bases, coordenadas na lâmina, nome do gene, locus do
mapeamento), multiFASTA.

18.2.4 Bases de dados


É possível fazer o download de sequências FASTA de interesse a partir de diver-
sas bases de dados, algumas bastante genéricas, outras mais específicas com rela-
ção ao organismo estudado. Provavelmente a fonte mais famosa é o site do NCBI:
https://www.ncbi.nlm.nih.gov/. A partir desse portal, pode-se escolher a base
de dados de interesse (tal como Protein ou Nucleotide), buscar pela entidade de inte-
resse (e.g., o nome do gene) e os conjuntos de sequências a serem baixados (sequên-
cias de nucleotídeos, transcritos ou de proteínas do gene.

18.2.5 Python
O pacote em Python que nos permite lidar com arquivos do tipo FASTA chama-se
SeqIO [?], que é a interface padrão para entrada e saída de sequências e faz parte do
conjunto de ferramentas para biologia molecular computacional chamado BioPython.
Código Significado
A Adenosina
C Citosina
G Guanina
T Timidina
U Uracila
R G A (puRina)
Y T U C (Pirimidina - do inglês pYrimidine)
K G T U (Cetona - do inglês Ketone)
M A C (grupo aMina)
S G C (interação forte - do inglês Strong interaction)
W A T U (interação fraca - do inglês Weak interaction)
B G T U C (não A) (B vem após A)
D G A T U (não C) (D vem após C)
H A C T U (não G) (H vem após G)
V G C A (não T, não U) (V vem após U)
N A C G T U (qualquer - aNy)
X mascarado
- lacuna de comprimento indeterminado
Tabela 18.1: Códigos de ácidos nucleicos suportados. Fonte: Wikipédia.

Entrada de sequências

RASCUNHO
A principal função é a Bio.SeqIO.parse(), que recebe como parâmetros um ma-
nipulador de arquivos (ou o nome do arquivo) e o nome do formato do arquivo e
devolve um iterador do tipo SeqRecord. Assim, podemos imprimir na tela todos os
identificadores das sequências contidas em um arquivo FASTA de duas formas:
• usando o nome do arquivo;

from Bio import SeqIO

for record in SeqIO.parse("example.fasta", "fasta"):


print(record.id)

• usando um manipulador para o arquivo.

from Bio import SeqIO

with open("example.fasta") as handle:


for record in SeqIO.parse(handle, "fasta"):
print(record.id)

Os dois exemplos acima usam um iterador, o que é ótimo quando se precisa dos
registros um a um, na mesma ordem em que eles aparecem no arquivo. Em alguns
casos, no entanto, é necessário ter acesso aos registros de forma aleatória, em uma
ordem qualquer. Para tanto, basta usarmos a função list do Python, de modo a
converter o iterador em uma lista.

from Bio import SeqIO

records = list(SeqIO.parse("example.fasta", "fasta"))


print(records[0].id) # first record
print(records[-1].id) # last record

Outra tarefa comum é indexar seus registros usando algum identificador. Para
arquivos pequenos, podemos usar a função Bio.SeqIO.to_dict(), de modo a con-
verter um iterador do tipo SeqRecord (ou uma lista) em um dicionário armazenado
em memória.

from Bio import SeqIO

record_dict = SeqIO.to_dict(SeqIO.parse("example.fasta", "fasta"))


print(record_dict["TcBrA4_Chr1"]) # use any record ID

A função Bio.SeqIO.to_dict() usa, por padrão, o identificador do registro


como chave para o dicionário, mas é possível especificar qualquer mapeamento que
se quiser com o argumento opcional key_function.
Para arquivos maiores, pode não ser possível armazenar tudo em memória, de
modo que a função Bio.SeqIO.to_dict() não será viável. Para esses casos, pode-
se usar a função Bio.SeqIO.index, embora também se possa levar em consideração
o módulo BioSQL.

RASCUNHO
No caso de o arquivo FASTA (ou seu manipulador) conter um, e apenas um, regis-
tro, pode-se usar a função Bio.SeqIO.read(), a qual também recebe um manipula-
dor e o formato do arquivo. O registro único será devolvido como um único objeto
SeqRecord. Se o arquivo não contiver nenhum registro ou tiver mais de um, uma
exceção é emitida.

from Bio import SeqIO

first_record = next(SeqIO.parse("example.fasta", "fasta"))

Saída de sequências
Para a escrita de registros em um arquivo, use a função Bio.SeqIO.write(), a qual
recebe um iterador do tipo SeqRecord (ou uma lista), um manipulador de saída (ou o
nome de um arquivo) e uma string informando o formato.

from Bio import SeqIO

sequences = ... # add code here


with open("output.fasta", "w") as output_handle:
SeqIO.write(sequences, output_handle, "fasta")

ou
from Bio import SeqIO

sequences = ... # add code here


SeqIO.write(sequences, "output.fasta", "fasta")

18.2.6 Exemplos
Exemplo de entrada e saída: filtragem por comprimento de sequência
Um exemplo prático de uso de arquivos FASTA é a manipulação ou filtragem dos
dados de alguma forma.
Por exemplo, vamos salvar em um arquivo FASTA todas as sequências cujo com-
primento seja menor que 300 nucleotídeos.
from Bio import SeqIO

short_sequences = [] # setup an empty list


for record in SeqIO.parse("cor6_6.gb", "genbank":
if len(record.seq) < 300:
# Add this record to our list.
short_sequences.append(record)

print("Found %i short sequences" % len(short_sequences))

SeqIO.write(short_sequences, "short_seqs.fasta", "fasta")


Uma versão mais curta envolve o conceito de list comprehensions.

RASCUNHO
from Bio import SeqIO

input_seq_iterator = SeqIO.parse("cor6_6.gb", "genbank")

# Build a list of short sequences.


short_sequences = [record for record in input_seq_iterator if len(record.seq) <
300]

print("Found %i short sequences." % len(short_sequences))

SeqIO.write(short_sequences, "short_seqs.fasta", "fasta")


Caso você esteja lidando com arquivos muito grandes, com milhares de registros,
você pode se beneficiar fazendo uso de um generator expression. Isso evita a criação
da lista completa de todos os registros desejados em memória.
from Bio import SeqIO

input_seq_generator = SeqIO.parse("core6_6.gb", "genbank")


short_seq_iterator = (record for record in input_seq_generator if
len(record.seq) < 300

SeqIO.write(short_seq_iterator, "short_seqs.fasta", "fasta")


Lembre que para formatos de arquivo sequenciais, como o FASTA, o método
Bio.SeqIO.write() recebe um iterador do tipo SeqRecord. A vantagem do có-
digo acima é que apenas um registro estará em memória a cada momento.
Nota: falar sobre os termos "a montante"e "a jusante"em lugar de "upstream"e
"downstream".

18.3 FASTA 2 line


Trata-se de uma variante do formato FASTA na qual não ocorre quebra de linha na lis-
tagem dos nucleotídeos ou aminoácidos e contém exatamente duas linhas por registro.

18.4 FASTQ

18.5 BED, GFF e GTF


https://www.ensembl.org/info/website/upload/bed.html

18.6 BAM
É possível armazenar leituras não mapeadas no formato BAM. Essa estratégia é usada,
por exemplo, pelo dorado. Uma das vantagens é o tamanho, que fica menor que o
mesmo conteúdo armazenado em formato FASTQ.GZ. O inconveniente é que nem
todas as ferramentas aceitam entrada no formato BAM, além do tempo de conversão

RASCUNHO
entre formatos. Quais outras vantagens há no uso de BAM para esse caso?

Exercícios
O exercício abaixo deve ser adaptado para o conteúdo deste capítulo, seguindo a se-
guinte solução:

#!/bin/bash

for i in ‘find output/ -type f -name ’*R2*’ | cut -d_ -f1 | uniq‘
do
cat ${i}_L007_R2.fastq ${i}_L008_R2.fastq > ${i}_R2.fastq
rm ${i}_L007_R1.fastq
rm ${i}_L007_R2.fastq
rm ${i}_L008_R1.fastq
rm ${i}_L008_R2.fastq
done

exit 0

① Considere que output/ é um subdiretório de seu diretório de trabalho atual e que


seu conteúdo consiste nos seguintes arquivos e diretórios:
a-s1-l7_R1.fastq b-s1-l7_R1.fastq boxPlot -> plot/boxPlot/
a-s1-l7_R2.fastq b-s1-l7_R2.fastq histogram -> plot/hist/
a-s1-l8_R1.fastq b-s1-l8_R1.fastq myProgram*
a-s1-l8_R2.fastq b-s1-l8_R2.fastq myScript*
a-s2-l7_R1.fastq b-s2-l7_R1.fastq plot/
a-s2-l7_R2.fastq b-s2-l7_R2.fastq scriptR/
a-s2-l8_R1.fastq b-s2-l8_R1.fastq scriptR1/
a-s2-l8_R2.fastq b-s2-l8_R2.fastq scriptR2/

(a) Liste todos os arquivos que possuem o termo “R2” como substring em seu
nome.
(b) Dos arquivos listados no item anterior, separe os identificadores que aparecem
antes do segundo hífen (“-”).
(c) A partir da listagem do item anterior, remova as linhas repetidas.
(d) Quantos identificadores únicos (diferentes) há? Não conte: use um comando
que forneça a resposta.

② Neste exercício iremos treinar nossas habilidades para lidar com entrada/saída (I/O,
do inglês Input/Output).

(a) Baixe o arquivo https://tritrypdb.org/common/downloads/Current_


Release/TcruziBrazilA4/fasta/data/TriTrypDB-58_TcruziBrazilA4_
Genome.fasta. Este FASTA contém o genoma do organismo Trypanosoma
cruzi, cepa Brazil A4.
(b) Visualize o conteúdo do arquivo e note que ele possui o símbolo ‘>’ na primeira

RASCUNHO
coluna da primeira linha, seguido por informações referentes à sequência de
nucleotídeos que se inicia na linha seguinte.
(c) Todas as linhas que contém nucleotídeos parecem ter o mesmo comprimento
(exceção feita à ultima linha de cada item). Descubra quantas colunas possuem
essas linhas.
(d) Com relação ao primeiro cromossomo, descubra em qual linha e em qual co-
luna se encontra o primeiro:
• A;
• C;
• G;
• T;
• N.
(e) Dado que o arquivo FASTA com que estamos trabalhando possui diversas en-
tradas, ou seja, é um arquivo multi-FASTA, liste todas as linhas de definição
de entrada FASTA deste arquivo.
(f) Descubra quantos itens (dentre cromossomos e contigs) há neste arquivo.

Explicar os conceitos de um arquivo FASTA e multiFASTA. Navegar em um ar-


quivo FASTA com os cromossomos de xto com o more e com o less. Fazer buscas
de cromossomos e padrões NNNN. Fazer o mesmo para um arquivo BED dos genes
de xto e procurar por alguns genes importantes. O mesmo para um arquivo de meta-
dados bem simples (contendo talvez apenas o nome da amostra, como macho, fêmea,
esquistossômulo e cercária).
Mostrar o conteúdo de um arquivo (FASTA, BED, GTF ou metadados) com os
comandos head, tail e cat e seus parâmetros. Ao mostrar o cat, iniciar concatenando
arquivos e depois apenas exibindo um deles.
Contar o número de nucleotídeos em um arquivo FASTA (ignorar a linha do cabe-
çalho com head ou tail). Como fazer para ignorar o \n final de cada linha? tr? fold?
split?
Contar o número de nucleotídeos em um arquivo multi-FASTA (ignorar cabeça-
lhos com grep -v)
Em um diretório cheio de arquivos FASTQ, conte o número de arquivos (pode
ser feito usando ls | wc -l; comentar sobre a incongruência entre o número de linhas
exibido na tela e o número de linhas contadas pelo wc).
Ordenar um arquivo que contenha os nomes de cromossomos de um organismo.
Ordenar em ordem reversa.
Crie um arquivo com três colunas: mês, número do mês e estação do ano. Ordene
esse arquivo em ordem alfabética do nome do mês (sort). Ordene-o de modo a mostrar
a sequência inversa dos meses no ano (sort -k2 -Rn). Ordene os meses por ordem
alfabética de estação de ano e numérica do número do mês (sort -k 3 -k 2n months).
Exercícios com o cut: obter a primeira coluna (-f1). A Primeira, a 4 e a 5 (-f1, 4,
5). Da primeira até a terceira (-f1-3). Da quarta em diante (-f4-). Talvez um exemplo
com BED seja legal.
A partir de um BED com colunas separadas com espaço em vez de <TAB> soli-
citar algo tal como acima (fazer uso de cut -d’ ’).
A partir de um arquivo BED ou GTF, listar as diferentes características existentes

RASCUNHO
(gene, mRNA). (sort -u). Contar quantas existem de cada característica (uniq -c?).
Obtenha uma lista de todos os pseudo-genes de xto (grep \tpseudo-gene\t).
A partir de um arquivo que contenha uma linha a menos, pedir para os alunos
descreverem a diferença entre os arquivos. O mesmo para uma pequena mudança
(alguma palavra) em um dos arquivos.
A partir de arquivos simples de metadados (somente o estágio do organismo) de
diferentes experimentos, descubra os estágios exclusivos e os comuns (comm). Quan-
tos são? (comm | wc -l).
Exercícios do curso da Coursera: Quantos cromossomos há no genoma? (grep ‘‘^>’’ | wc -l ou grep -c ‘‘^>’’
Descubra quantos e quais são os genes que possuem o maior número de isoformas.
Isolar a coluna dos nomes das Smps e talvez extrair o ’.’ seguido do número da
isoforma e contar com o uniq -c.
Procurar no GFF por um determinado produto de interesse. Quais são os genes
que possuem esse produto na descrição? (Usar o grep. Há algum valor que esteja na
coluna de products e que possa ser confundido com o valor de alguma outra coluna?
Como fazer para resolver isso?).
Dadas duas listas de genes, que podem ser de genes diferencialmente expressos,
encontrar os genes que são comuns aos dois conjuntos. 1.a solução: ordenar os dois
conjuntos, concatenar e fazer um uniq -c. 2.a solução: comm. Quais são os genes
exclusivos a cada conjunto?
Quantos genes estão na fita + e na fita -?
Quantos genes existem em cada cromossomo?
Dados três conjuntos de genes, quais genes são comuns aos três? (Usar o comm
mais de uma vez).
Teste do Coursera.
SeqIO https://biopython.org/wiki/SeqIO

① Liste duas características que fogem do padrão do formato FASTA nas duas linhas
abaixo.

>gene1|Trypanosoma cruzi|SNP42|length=45
ACTGGTAGACCCGATTG[A/T]CACGATGGCGATTTCGACATCGT

② Escreva um one-liner que devolva o número de nucleotídeos presentes em um


arquivo no formato FASTA. Faça o mesmo para um arquivo no formato multi-
FASTA.
R:

$> grep -c "^>" file.fasta


$> grep -v "^>" file.fasta | wc | awk ’{print $3 - $1}’

RASCUNHO
CAPÍTULO 19
OUTROS TÓPICOS

19.1 Submissão de resultados


Incluir aqui as ações necessárias para submeter arquivos resultantes de pipelines com-
pletos e que eventualmente foram publicados em artigo. Listar as especificidades de
cada base de dados e as opções disponíveis para submissão, tais como FTP ou Aspera.

• SRA (só aceita FASTQ?).


• GEO (só aceita BAM?).

RASCUNHO
Esses arquivos devem ficar armazenados em um subdiretório do projeto, com a
numeração mais alta possível.

• filtragem de reads (considerar alterar readStats para qualityControl) (rodar um ma-


peador, como o Tophat2, por exemplo, diretamente nos dados brutos, com diferen-
tes parâmetros, para tirar algumas conclusões como: há diferença entre as lanes
(efeito de lote), ocorreu algum problema entre os pares R1 e R2?);
• análise de genes diferencialmente expressos (DEGs);
• montagem de transcriptoma de novo;
• análise de ChIP-seq;
• análise de genes de fusão;
• montagem de genoma;
• comparação entre transcriptomas;
• análise de elementos de transposição;
• identificação de long non-coding RNAs;
• SNPs.

87
• diferentes processamentos a serem feitos tomando o gene como ponto central:
– estrutura
* promotor
* transposon
* RNA splicing
* SNP/InDel
* UTR length
– expressão
* DEGs (phenotype)
* experiment
* gene info (sequence / ref)
* function (GO, KEGG, GSEA, etc.)
* interaction (PPI, KDA)
* clustering (heatmap, time series)
* co-expression
* previous study
– regulação
* lncRNA regulation
* micRNA regulation
* (active/inhibit)
• saturation plot (NOISeq, RNAseQC::plot_saturation_curve, MOMA::make_saturation.plots.r,

RASCUNHO
ATACseqQC::saturationPlot).

• Sequencing depth: quanto mais for sequenciado, melhor —> custo maior —> mais
ruído?
• mais reads —> mais poder estatístico dos resultados —> maior custo financeiro.

Ter como tarefa durante o curso fazer um cheat sheet sobre os principais comandos
(mais úteis).
Parte V

Apêndice

RASCUNHO

89
RASCUNHO
APÊNDICE A
EPÍLOGO

Referências
• Rascunho de apostila de curso para pipelines em Bioinformática.

• Dropbox/exatas/computacao/cursos/introducaoAoLinux/references/slides/SemBioqIntr
odBioinfoLinuxeShell.pdf

RASCUNHO

91
RASCUNHO

Você também pode gostar