저는 Python 스크립트를 몇 개 가지고 있고 이를 다시 작성하는 중입니다. 나는 그들 모두와 같은 문제가 있습니다.
올바른 UNIX 도구처럼 작동하도록 프로그램을 작성하는 방법은 나에게 명확하지 않습니다.
이것 때문에
$ cat characters | progname
이
$ progname characters
동일한 출력을 생성해야 합니다.
Python에서 찾을 수 있는 가장 가까운 것은 fileinput 라이브러리입니다. 불행하게도 저는 Python 스크립트를 다시 작성하는 방법을 잘 모릅니다. 모든 스크립트는 다음과 같습니다.
#!/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
fileinput 라이브러리는 stdin이 있으면 stdin을 처리하고, 파일이 있으면 파일을 처리합니다.그러나 단일 행을 반복합니다.
import fileinput
for line in fileinput.input():
process(line)
정말 이해가 안 돼요. 작은 파일을 다루고 있거나 파일을 많이 다루지 않는다면 이것이 분명해 보일 수 있습니다. 그러나 내 목적에 따르면 이는 위에서 언급한 것처럼 단순히 전체 파일을 열고 문자열로 읽는 것보다 훨씬 느립니다.
현재 위의 스크립트를 다음과 같이 실행합니다.
$ pythonscript textfilename1 > textfilename2
하지만 나는 파이프라인에서 이 도구(및 그 형제)를 실행할 수 있기를 원합니다.
$ grep pattern textfile1 | pythonscript | pythonscript | pythonscript > textfile2
답변1
파일 이름이 인수로 제공되었는지 확인하고, 그렇지 않으면 파일 이름을 읽습니다 sys.stdin
.
이 같은:
if len(sys.argv) > 0:
f = open(sys.argv[1])
else:
f = sys.stdin
이 모듈을 사용한다는 점을 제외하면 Mikel의 답변과 유사합니다 sys
. 거기에 넣으면 이유가 있을 거라고 생각했는데...
답변2
왜 안되지?
files = sys.argv[1:]
if not files:
files = ["/dev/stdin"]
for file in files:
f = open(file)
...
답변3
내가 가장 좋아하는 방법은... (이것은 다음과 같은 멋진 작은 Linux 블로그에서 가져온 것입니다.개척자 계곡)
#!/usr/bin/env python
import argparse, sys
parser = argparse.ArgumentParser()
parser.add_argument('filename', nargs='?')
args = parser.parse_args()
if args.filename:
string = open(args.filename).read()
elif not sys.stdin.isatty():
string = sys.stdin.read()
else:
parser.print_help()
제가 가장 좋아하는 점은 블로거가 말했듯이 입력 없이 실수로 호출하면 어리석은 메시지만 출력한다는 것입니다. 또한 기존의 모든 Python 스크립트에 잘 통합되므로 이를 포함하도록 모두 수정했습니다.