2013-07-23 2 views
3

한 줄씩 파일을 처리하고 싶습니다. 그러나 나는 일반적으로 배관에 의해 수행하는 먼저 정렬 할 필요가 :리눅스 출력을 파이프하는 가장 좋은 방법

sort --key=1,2 data |./script.py. 

최고의 파이썬 내에서 일종의 전화를 무엇입니까? 온라인으로 검색하면 subprocess 또는 sh 모듈이있을 수 있습니다. 필자는 파일을 메모리에 저장하고 파이썬에서 정렬하기를 원하지 않습니다.

+3

FYI : sort는 메모리의 파일을 읽어야합니다. – SheetJS

+2

정확하게는 아닙니다. 리눅스 정렬은 그것에 대해 매우 영리하며 외부 메모리 정렬 알고리즘을 사용하여 RAM보다 더 큰 파일을 정렬 할 수 있습니다. Seehttp : //stackoverflow.com/questions/930044/how-could-the-unix-sort-command-sort-a-very-large-file. – phoenix

+0

어쩌면 정렬은 메모리에 파일을 읽을 필요가 없지만, 다시 파이썬은 왜 그렇게할까요? ('sort'가 똑똑 할 수 있다면 파이썬도 가능합니다.) – kojiro

답변

3

쉽습니다. subprocess.Popen을 사용하여 정렬을 실행하고 stdout을 읽어 데이터를 가져옵니다.

import subprocess 
myfile = 'data' 
sort = subprocess.Popen(['sort', '--key=1,2', myfile], 
    stdout=subprocess.PIPE) 
for line in sort.stdout: 
    your_code_here 
sort.wait() 
assert sort.returncode == 0, 'sort failed' 
+0

sort.wait()는 무엇을합니까? 어쨌든 정렬이 완료되기 전에 정렬이 완료되어야하는 것처럼 보입니다. – phoenix

+0

for 루프는 프로세스가 프로세스를 종료 할 때까지 stdout 프로세스를 읽습니다 (보통 프로세스 종료시에 프로세스가 자유 롭습니다. 원하는 경우 초기 닫습니다). wait() 호출은 프로세스 종료를 기다리고 리턴 코드를받습니다. 이것은 리눅스에서 좀비 프로세스를 시스템 프로세스 테이블에서 제거하기 때문에 중요합니다. – tdelaney

+0

고맙습니다. – phoenix

0

나는 종류의 메모리에 모든 데이터를 읽어, 그래서 당신은 아무것도을 수상합니다 모르겠지만 당신은 파이프 라인

>>> subprocess.check_output("ls", shell = True) 
'1\na\na.cpp\nA.java\na.php\nerase_no_module.cpp\nerase_no_module.cpp~\nWeatherSTADFork.cpp\n' 
>>> subprocess.check_output("ls | grep j", shell = True) 
'A.java\n' 

경고 subprocessshell=True을 사용하여 사용할 수있는 것으로 판단
shell = True로 시스템 쉘을 호출하면 신뢰할 수없는 입력과 결합 할 경우 보안 상 위험 할 수 있습니다. 자세한 내용은 자주 사용하는 인수 아래의 경고를 참조하십시오.

+0

고마워. Sort는 전체 파일을 메모리로 읽지 않습니다. http://stackoverflow.com/questions/930044/how-could-the-unix-sort-command-sor t-a-very-large-file을 참조하십시오. . – phoenix

0

나는 (모두 그대로 인용) this page

@Eli Courtwright에서 내가 원하는 대답, 당신의 질문에 대답 생각 : 여기

외부 프로그램과 장점을 호출하는 방법에 대한 요약이다 각각의 단점 :

  1. os.system("some_command with args")는 시스템의 쉘 명령 및 인수를 전달합니다. 이 방법으로 한 번에 여러 명령을 실행하고 파이프와 입출력 방향 재 지정을 설정할 수 있기 때문에 이점이 좋습니다. 예를 들어,
    os.system("some_command < input_file | another_command > output_file")
    그러나 편리하기는하지만 공백과 같은 셸 문자의 이스케이프 처리는 수동으로 처리해야합니다. 반면에 이것은 쉘 명령이면서 실제로는 외부 프로그램.
    http://docs.python.org/lib/os-process.html

  2. stream = os.popen("some_command with args")는 당신에게 당신이 그 과정에 대한 표준 입력/출력에 액세스하는 데 사용할 수있는 파일 - 류의 객체를 제공하는 것을 제외하고 os.system 같은 일을 할 것입니다. 모든 3 가지 I/O를 약간 다르게 처리하는 popen의 다른 변종이 있습니다. 모든 것을 문자열로 전달하면 명령이 셸로 전달됩니다. 목록으로 전달하면 아무 것도 피할 걱정할 필요가 없습니다.
    http://docs.python.org/lib/os-newstreams.html

  3. subprocess 모듈의 Popen 클래스입니다. 이것은 os.popen의 대체품으로 의도되었지만 포괄적이기 때문에 약간 더 복잡하다는 단점이 있습니다. 예를 들어,
    print Popen("echo Hello World", stdout=PIPE, shell=True).stdout.read()
    대신
    print os.popen("echo Hello World").read()
    을 말하고 싶지만하지만 하나 개의 통합 클래스 대신에 4 개 개의 다른는 popen 기능 거기에 모든 옵션을 가지고 좋은 것입니다.
    http://docs.python.org/lib/node528.html

  4. subprocess 모듈에서 call 기능. 이것은 기본적으로 Popen 클래스와 같으며 모든 동일한 인수를 사용하지만 명령이 완료 될 때까지 대기하고 리턴 코드를 제공합니다. 예를 들면 :
    return_code = call("echo Hello World", shell=True)
    http://docs.python.org/lib/node529.html

  5. os 모듈은 또한 당신이 C 프로그램에서 거라고 포크/간부/스폰 모든 기능을 가지고 있지만, 내가 직접 사용하지 않는 것이 좋습니다.

subprocess 모듈을 사용해야합니다.

+0

감사하지만 shell = True가 사용되지 않을 것이라고 생각했습니다. – phoenix

+0

당신은 나보다 잘 알고있을 것입니다. 저는 여전히 파이썬 초보자입니다. – liang

관련 문제