Sou monitor de um professor na faculdade e uma das minhas tarefas é corrigir alguns trabalhos.
A turma tem uns 40 alunos e eles farão 3 trabalhos ao longo do semestre. No final do curso, preciso fazer um relatório para o professor, indicando quais alunos estão de recuperação, reprovados ou aprovados.
Rapidamente fiz um programa em Python que lê uma lista de alunos e suas notas e imprime na tela a situação de cada um. O código ficou mais ou menos assim:
import sys
for linha in sys.stdin:
linha = linha.split(';')
aluno = linha[0]
trabalho1 = int(linha[1])
trabalho2 = int(linha[2])
trabalho3 = int(linha[3])
media = (trabalho1 + trabalho2 + trabalho3) / 3
print(aluno + ': ', end='')
if media >= 5:
print('Aprovado')
elif media >= 3:
print('Recuperação')
else:
print('Reprovado')
Não tem problema se você não manja de Python, o importante aqui é entender que esse código lê várias linhas do teclado na forma:
Nome do aluno;Nota1;Nota2;Nota3
E imprime na tela algo como:
Nome do aluno: Aprovado
A execução do código é a seguinte:
$ python media.py
> João da Silva;8;7;9
João da Silva: Aprovado
> Larissa Souza;10;9;10
Larissa Souza: Aprovado
> Mario Oliveira;5;4;5
Mario Oliveira: Recuperação
> Pedro Carvalho;3;0;1
Pedro Carvalho: Reprovado
Embora o programa funcione, existem alguns detalhes que ainda dificultam a rotina de gerar o relatório, vamos entender quais são:
O programa imprime imediatamente depois que digito, deixando o resultado final confuso.
Dá muito trabalho rodar de novo. Se eu esquecer de um aluno, preciso digitar 40 nomes com 3 notas cada de novo.
Se o programa lesse os alunos e notas de um arquivo, daria para modificar só uma linha facilmente. Uma opção é alterar o código para trabalhar com arquivos. Essa alternativa é viável porque o código é meu e eu sei trabalhar com Python. Ficaria mais ou menos assim:
arquivo = open('notas.txt', 'r') #abrindo arquivo
for linha in arquivo: #lendo do arquivo
linha = linha.split(';')
aluno = linha[0]
...
Entendendo o redirecionamento
Nem sempre temos o luxo de ter acesso ao código fonte dos programas que usamos. Então como podemos fazer para ler as informações de um arquivo e direcionar cada linha para o nosso programa sem mexer no código?
Em sistemas baseados no Unix (como é o caso do Linux e do Mac), todos os programas são associados a uma entrada e saída padrão. Em geral, a entrada é o teclado e a saída é a tela (terminal). Podemos redirecionar tanto a entrada quanto a saída padrão de qualquer programa sem mexer no código, podendo facilmente ler e escrever em arquivos.
Redirecionando a entrada
Para redirecionar a entrada do código original, basta utilizar o caractere < na hora de rodar o programa, indicando um arquivo de entrada. Então vamos criar o arquivo notas.txt com o conteúdo:
João da Silva;8;7;9
Larissa Souza;10;9;10
Mario Oliveira;5;4;5
Pedro Carvalho;3;0;1
Rodando o programa da seguinte forma:
$ python media.py < notas.txt
João da Silva: Aprovado
Larissa Souza: Aprovado
Mario Oliveira: Recuperação
Pedro Carvalho: Reprovado
O resultado já ficou muito melhor. Agora posso copiar e colar a saída e mandar para o professor tranquilamente. Também posso mudar o nome do arquivo a ser lido com facilidade.
Modificando o código para escrever num arquivo
Já melhorou bastante, porém estamos lidando apenas com 4 alunos. E se fossem 1000? Copiar 1000 linhas do terminal não é nada produtivo. Seria uma boa jogar a saída num arquivo também, certo?
Podemos fazer isso modificando o nosso código, da seguinte forma:
import sys
saida = open('resultado.txt', 'w') # abrindo arquivo de saida
for linha in sys.stdin:
linha = linha.split(';')
aluno = linha[0]
trabalho1 = int(linha[1])
trabalho2 = int(linha[2])
trabalho3 = int(linha[3])
media = (trabalho1 + trabalho2 + trabalho3) / 3
saida.write(aluno + ': ') # escrevendo no arquivo
if media >= 5:
saida.write('Aprovado\n') # escrevendo no arquivo
elif media >= 3:
saida.write('Recuperação\n') # escrevendo no arquivo
else:
saida.write('Reprovado\n') # escrevendo no arquivo
saida.close() # fechando o arquivo de saida
Observe que modificamos algumas boas linhas de código. Meio trabalhoso, não acha?
Redirecionando a saída
Que tal utilizarmos o redirecionamento também? É muito mais cômodo porque não vamos mexer em código.
Para redirecionar a saída do código original, basta utilizar o caractere > na hora de rodar o programa, de forma semelhante ao redirecionamento da entrada:
$ python media.py > resultado.txt
> João da Silva;8;7;9
> Larissa Souza;10;9;10
> Mario Oliveira;5;4;5
> Pedro Carvalho;3;0;1
E se olharmos o conteúdo de resultado.txt, veremos:
João da Silva: Aprovado
Larissa Souza: Aprovado
Mario Oliveira: Recuperação
Pedro Carvalho: Reprovado
Redirecionando entrada e saída ao mesmo tempo
Uma coisa legal sobre o redirecionamento é que podemos fazer uma combinação. Não há nenhum problema em redirecionar tanto a entrada quanto a saída, isto é, podemos realizar o redirecionamento de saída e entrada ao mesmo tempo, veja como:
$ python media.py < notas.txt > resultado.txt
Quando fazemos esse redirecionamento o nosso programa primeiro lê o arquivo notas.txt e depois escreve em resultado.txt.
Truncamento
Agora os principais detalhes foram resolvidos, vou corrigir os trabalhos e gerar o relatório para o professor.
Como a turma é tanto para alunos do curso de Ciência da Computação como para alunos de Sistemas de Informação, decidi colocar as notas em dois arquivos diferentes: notas_cc.txt e notas_si.txt. Seus conteúdos são mais ou menos o seguinte:
notas_cc.txt
Julia Aparecida;8;9;9
Gabriel Russo;2;4;2
notas_si.txt
Danilo Gomes;10;9;10
Horacio Soares;5;7;4
Vou rodar meu programa duas vezes e meu relatório estará pronto:
O que houve com os alunos de Ciência da Computação? Eles deveriam estar no arquivo também.
O problema é que quando redirecionamos a saída de um programa para um arquivo, o sistema operacional trunca o arquivo antes, isto é, apaga todo seu conteúdo. Não é isso que queremos… E agora?
Podemos redirecionar a saída com os caracteres >>, que fazem exatamente a mesma coisa com a diferença de que o arquivo não é truncado. Veja:
Na primeira vez, truncamos o arquivo e escrevemos. Na segunda, apenas escrevemos. Olhando para o conteúdo de resultado.txt vemos:
Julia Aparecida: Aprovado
Gabriel Russo: Reprovado
Danilo Gomes: Aprovado
Horacio Soares: Aprovado
Para saber mais
Além de ler e escrever em arquivos, com esses redirecionamentos é possível fazer os programas conversarem, ou seja, podemos redirecionar a saída de um programa para a entrada de outro.
O programa ps com a flag -x imprime todos os processos que estão rodando nesse momento. Muitas vezes, esta lista é enorme e fica muito difícil procurar um processo. Podemos utilizar o programa grep para filtrar esses resultados.
O grep funciona de várias formas, mas uma delas é procurar um texto na entrada. Mas como redirecionar a saída do ps para a entrada do grep ?
Poderíamos utilizar um arquivo para guardar a saída e depois utilizá-lo como entrada, porém podemos fazer isso diretamente utilizando o caractere | (chama-se pipe). Basicamente, pegamos a saída padrão de um programa e jogamos para a entrada padrão de outro. Vamos ver um exemplo:
Agora que eu sei que meu processo tem o PID 41891, eu posso rodar kill 41891 para fechar o Eclipse travado.
Resumindo
Nesse post aprendemos que é possível ler e escrever em arquivos sem precisar mexer no código de nossos programas. Para fazer isso, utilizamos os seguintes redirecionamentos:
< para redirecionar a entrada
> para redirecionar a saída truncando (apagando) o arquivo
>> para redirecionar a saída sem truncar o arquivo
Que tal aprender mais sobre o Shell e Linux no geral? Aqui na Alura temos diversos cursos online de Linux para você aprender desde a estrutura básica do Linux como também os principais programas e comandos desse sistema operacional.
Lendo e escrevendo arquivos com o redirecionamento no Shell
Sou monitor de um professor na faculdade e uma das minhas tarefas é corrigir alguns trabalhos.
A turma tem uns 40 alunos e eles farão 3 trabalhos ao longo do semestre. No final do curso, preciso fazer um relatório para o professor, indicando quais alunos estão de recuperação, reprovados ou aprovados.
Rapidamente fiz um programa em Python que lê uma lista de alunos e suas notas e imprime na tela a situação de cada um. O código ficou mais ou menos assim:
Não tem problema se você não manja de Python, o importante aqui é entender que esse código lê várias linhas do teclado na forma:
E imprime na tela algo como:
A execução do código é a seguinte:
Embora o programa funcione, existem alguns detalhes que ainda dificultam a rotina de gerar o relatório, vamos entender quais são:
Se o programa lesse os alunos e notas de um arquivo, daria para modificar só uma linha facilmente. Uma opção é alterar o código para trabalhar com arquivos. Essa alternativa é viável porque o código é meu e eu sei trabalhar com Python. Ficaria mais ou menos assim:
Entendendo o redirecionamento
Nem sempre temos o luxo de ter acesso ao código fonte dos programas que usamos. Então como podemos fazer para ler as informações de um arquivo e direcionar cada linha para o nosso programa sem mexer no código?
Em sistemas baseados no Unix (como é o caso do Linux e do Mac), todos os programas são associados a uma entrada e saída padrão. Em geral, a entrada é o teclado e a saída é a tela (terminal). Podemos redirecionar tanto a entrada quanto a saída padrão de qualquer programa sem mexer no código, podendo facilmente ler e escrever em arquivos.
Redirecionando a entrada
Para redirecionar a entrada do código original, basta utilizar o caractere
<
na hora de rodar o programa, indicando um arquivo de entrada. Então vamos criar o arquivonotas.txt
com o conteúdo:Rodando o programa da seguinte forma:
O resultado já ficou muito melhor. Agora posso copiar e colar a saída e mandar para o professor tranquilamente. Também posso mudar o nome do arquivo a ser lido com facilidade.
Modificando o código para escrever num arquivo
Já melhorou bastante, porém estamos lidando apenas com 4 alunos. E se fossem 1000? Copiar 1000 linhas do terminal não é nada produtivo. Seria uma boa jogar a saída num arquivo também, certo?
Podemos fazer isso modificando o nosso código, da seguinte forma:
Observe que modificamos algumas boas linhas de código. Meio trabalhoso, não acha?
Redirecionando a saída
Que tal utilizarmos o redirecionamento também? É muito mais cômodo porque não vamos mexer em código.
Para redirecionar a saída do código original, basta utilizar o caractere
>
na hora de rodar o programa, de forma semelhante ao redirecionamento da entrada:E se olharmos o conteúdo de
resultado.txt
, veremos:Redirecionando entrada e saída ao mesmo tempo
Uma coisa legal sobre o redirecionamento é que podemos fazer uma combinação. Não há nenhum problema em redirecionar tanto a entrada quanto a saída, isto é, podemos realizar o redirecionamento de saída e entrada ao mesmo tempo, veja como:
Quando fazemos esse redirecionamento o nosso programa primeiro lê o arquivo
notas.txt
e depois escreve emresultado.txt
.Truncamento
Agora os principais detalhes foram resolvidos, vou corrigir os trabalhos e gerar o relatório para o professor.
Como a turma é tanto para alunos do curso de Ciência da Computação como para alunos de Sistemas de Informação, decidi colocar as notas em dois arquivos diferentes:
notas_cc.txt
enotas_si.txt
. Seus conteúdos são mais ou menos o seguinte:Vou rodar meu programa duas vezes e meu relatório estará pronto:
Olhando o conteúdo de
resultado.txt
:O que houve com os alunos de Ciência da Computação? Eles deveriam estar no arquivo também.
O problema é que quando redirecionamos a saída de um programa para um arquivo, o sistema operacional trunca o arquivo antes, isto é, apaga todo seu conteúdo. Não é isso que queremos… E agora?
Podemos redirecionar a saída com os caracteres
>>
, que fazem exatamente a mesma coisa com a diferença de que o arquivo não é truncado. Veja:Na primeira vez, truncamos o arquivo e escrevemos. Na segunda, apenas escrevemos. Olhando para o conteúdo de
resultado.txt
vemos:Para saber mais
Além de ler e escrever em arquivos, com esses redirecionamentos é possível fazer os programas conversarem, ou seja, podemos redirecionar a saída de um programa para a entrada de outro.
O programa
ps
com a flag-x
imprime todos os processos que estão rodando nesse momento. Muitas vezes, esta lista é enorme e fica muito difícil procurar um processo. Podemos utilizar o programagrep
para filtrar esses resultados.O
grep
funciona de várias formas, mas uma delas é procurar um texto na entrada. Mas como redirecionar a saída dops
para a entrada dogrep
?Poderíamos utilizar um arquivo para guardar a saída e depois utilizá-lo como entrada, porém podemos fazer isso diretamente utilizando o caractere
|
(chama-se pipe). Basicamente, pegamos a saída padrão de um programa e jogamos para a entrada padrão de outro. Vamos ver um exemplo:Agora que eu sei que meu processo tem o PID 41891, eu posso rodar
kill 41891
para fechar o Eclipse travado.Resumindo
Nesse post aprendemos que é possível ler e escrever em arquivos sem precisar mexer no código de nossos programas. Para fazer isso, utilizamos os seguintes redirecionamentos:
<
para redirecionar a entrada>
para redirecionar a saída truncando (apagando) o arquivo>>
para redirecionar a saída sem truncar o arquivoQue tal aprender mais sobre o Shell e Linux no geral? Aqui na Alura temos diversos cursos online de Linux para você aprender desde a estrutura básica do Linux como também os principais programas e comandos desse sistema operacional.
FIQUE POR DENTRO
Compartilhe:
Gabriel Russo
Próximo ArtigoPortfólio na área de tecnologia: um guia para construir um ideal!