Eu tenho alguns scripts Python por aí e estou trabalhando para reescrevê-los. Eu tenho o mesmo problema com todos eles.
Não é óbvio para mim como escrever os programas para que eles se comportem como ferramentas unix apropriadas.
Porque isso
$ cat characters | progname
e isto
$ progname characters
deve produzir a mesma saída.
A coisa mais próxima que pude encontrar no Python foi a biblioteca de entrada de arquivos. Infelizmente, eu realmente não vejo como reescrever meus scripts Python, todos com a seguinte aparência:
#!/usr/bin/env python
# coding=UTF-8
import sys, re
for file in sys.argv[1:]:
f = open(file)
fs = f.read()
regexnl = re.compile('[^\s\w.,?!:;-]')
rstuff = regexnl.sub('', fs)
f.close()
print rstuff
A biblioteca fileinput processa stdin se houver um stdin e processa um arquivo se houver um arquivo. Mas ele itera sobre linhas únicas.
import fileinput
for line in fileinput.input():
process(line)
Eu realmente não entendo isso. Eu acho que se você estiver lidando com arquivos pequenos ou se não estiver fazendo muito com os arquivos, isso pode parecer óbvio. Mas, para meus propósitos, isso torna muito mais lento do que simplesmente abrir o arquivo inteiro e lê-lo em uma string, como acima.
Atualmente eu corro o script acima como
$ pythonscript textfilename1 > textfilename2
Mas eu quero poder executá-lo (e seus irmãos) em tubos, como
$ grep pattern textfile1 | pythonscript | pythonscript | pythonscript > textfile2
Respostas:
Por que não apenas
fonte
sys.stdin
deve ser usado, pois é mais portátil do que o caminho codificado para o arquivo.sys.stdin
deve ser usado em vez disso, como diz Piotrsys.stdin
é um arquivo, e já está aberto e não deve ser fechado. Impossível lidar como um argumento de arquivo sem pular os bastidores.f
ou usar um gerenciador de contexto, precisa de algo mais complexo. Veja minha nova resposta como uma alternativa.Verifique se um nome de arquivo é fornecido como argumento, ou então leia de
sys.stdin
.Algo assim:
É semelhante à resposta de Mikel, exceto que ele usa o
sys
módulo. Eu acho que se eles tiverem lá, deve ser por uma razão ...fonte
"open(/dev/stdin")
comsys.stdin
.if len(sys.argv)>1:
vez deif sys.argv[1]:
obter um erro de índice fora do intervaloMinha maneira preferida de fazer isso acaba sendo ... (e isso é retirado de um pequeno e agradável blog do Linux chamado Harbinger's Hollow )
A razão pela qual eu mais gostei disso é que, como diz o blogueiro, ela apenas envia uma mensagem boba se for chamada acidentalmente sem entrada. Ele também se encaixa tão bem em todos os meus scripts Python existentes que os modifiquei para incluí-lo.
fonte
isatty
e resgate não está de acordo com a filosofia dos filtros Unix.isatty
verruga, isso cobre um terreno útil e importante que não foi encontrado nas outras respostas, de modo que obtém meu voto positivo.fonte
/dev/stdin
não estivesse disponível em todos os meus sistemas.Estou usando esta solução e funciona como um encanto. Na verdade, eu estou usando em um script calle unaccent que minúsculas e remove acentos de uma determinada string
Acho que o melhor momento em que vi essa solução foi aqui .
fonte
Se o seu sistema não possui
/dev/stdin
, ou você deseja uma solução mais geral, tente algo mais complicado, como:fonte
-
várias vezes. :)