2016-11-18 2 views
2

bash (OSX)에서 ~ 300,000 줄의 파일에서 ~ 5000 줄을 추출해야합니다. 나는 10 개 라인 만 추출하려고하면 대용량 텍스트 파일에서 많은 수의 줄을 추출합니다.

sed '128082p;128083p;...(4996 numbers)....;159845q;d' file > output 

를 실행하면 오류를

sed: 1: "128082p;128083p;128084p ...": command expected 

이 같은 명령이 작동을 제공합니다. 반면에 실행 중

for i in `cat line_file`; do sed -n "$ip" file; done >> output 

은 ~ 5000 행 이상인 파일을 만듭니다. 두 경우 모두 올바른 명령이 무엇입니까?

편집 : 이것은 숫자 범위가 아닙니다.

+0

@Sundeep 숫자 목록은 사용자가 게시 한 번호가 아닌 '128082 + 5000 = 133082' 범위로 표시됩니다 :'159845 '. – sorontar

+0

@sorontar, true .. 질문이 불투명합니다.하지만 OP가 범위를 원한다고 생각합니다. (어떤 것이 든간에) – Sundeep

+0

왜 '; d'가 있습니까? 그리고'sed -n '은 128082,133082p; 133083q'file> out'은 어떨까요? 행운을 빕니다. – shellter

답변

3

그의 도움에 대한 Jonathan Leffler의 모자 팁.

그것은 외모에 전달 될 수있는 스크립트의 각 라인의 크기에 하드 제한이 (맥 OS 10.12.1 현재) 맥 OS에 사용되는 BSD sed 같은 : 2048를 바이트. 명령 줄 인수 (암시 적 첫 번째 피연산자로, 또는 명시 적으로 -e를 통해 옵션)로 전달하면 당신이 그랬던 것처럼

는, 스크립트는 일반적으로 하나의 라인으로 전달됩니다.

한 줄의 길이가 너무 길어지면 유감스럽게도 맹목적으로 차단되어 일반적으로 겉으로보기에 무작위로 문법 오류가 발생합니다.

해결 방법 두 가지가 있습니다

  • 대신 ;의 스크립트가 \n (줄 바꿈)로 분리 명령에 의해서만 짧은만큼 줄이 포함되어 있는지 확인 및/또는 여러 걸쳐 -e 옵션을 스크립트를 분할 (성가신).

  • 모든 명령을 어쨌든 \n보다는 ;로 구분해야하는 경우에 -f 옵션을 사용하여 파일를 통해 전체 스크립트를 제공합니다.
    드문 경우이지만 스크립트가 단일 명령 줄 (시스템에 의해 부과 된 제한 인 - 아래 참조)에 적합하지 않을 경우 -f을 사용하는 것이 유일한 옵션입니다. 여기

이 너무 깁니다 그 명령 줄 스크립트의 예 : 스크립트가 2048 바이트 잎에서 오프 라인에만 하나를 절단, 문법적으로 정확

$ sed -n "$(printf '%sp;' {1..432})" <<<'line 1' 
sed: 1: "1p;2p;3p;4p;5p;6p;7p;8p ...": command expected # !! ERROR 

에도 불구하고 그것은 겉보기 임의의 command expected 오류의 결과, 잘못된 것입니다.이 경우

는 제한을 해결 작업은 간단하다 : \n;를 대체하여, 각각의 라인은 충분히 짧아 :

$ sed -n "$(printf '%sp\n' {1..432})" <<<'line 1' 
line 1 # OK 

이미 줄 번호의 파일을 가지고 있기 때문에 - line_file을 - 당신은 그것에서 \n 단락 지어진 스크립트를 작성하는 보조sed 명령을 사용할 수 있습니다

$ sed -n "$(sed 's/$/p/' line_file)" file > output 
012 3,516,

는 여기에 문제를 해결 단락 지어진 명령이 \n을하는 파일-f를 통해 전달 된 스크립트를 통해 문제를 해결하는 방법은 다음과 같습니다

$ printf '%sp\n' {1..432} > script.sed # Create script file with \n-separated commands. 
$ sed -n -f "script.sed" <<<'line 1' # Pass script file via -f 
line 1 # OK 

참고 : 프로세스 대체 (sed -n -f <(printf ...) ...) 등을 사용하여 ad-hoc 스크립트 파일은 이 아니기 때문에이 작동하지 않습니다.

전체적으로입니다. macOS에서 sed (10.12 현재)과 같은 외부 유틸리티를 호출하기위한 명령 줄의 길이는 262144 (256KB, 확인 된 숫자는 getconf ARG_MAX)이며, 실제로 환경 변수 블록의 크기가 역할.
그러나이 한도를 초과하면 더 유용한 오류 메시지 인 Argument list too long이 표시됩니다.

+2

크기가 제한되어 있지만 작은 명령에 대한 작업으로 인해 크기 제한이 의심 스럽지만 몰랐습니다. . "sed -n"$ (sed 's/$/p /'line_file) "파일> 출력"명령이 1 분 안에 작동했습니다. 매우 도움이되는 설명을위한 1+. – aish1249

관련 문제