텍스트 파일에서 조각을 가져오는 가장 좋은 방법은 무엇입니까?

텍스트 파일에서 조각을 가져오는 가장 좋은 방법은 무엇입니까?

거대한 텍스트 파일에서 20~45행을 추출하는 좋은 방법은 무엇입니까? 물론 비대화형입니다!

답변1

더 간단하다:

sed -n '20,45p;45q' < textfile

-n 플래그는 기본 출력을 비활성화합니다. "20,45"는 20행부터 45행(포함)까지의 주소를 지정합니다. "p" 명령은 현재 줄을 인쇄합니다. q 이 줄을 인쇄한 후 종료됩니다.

답변2

당신은 시도 할 수 있습니다:

cat textfile | head -n 45 | tail -n 26

또는

cat textfile | awk "20 <= NR && NR <= 45" 

고쳐 쓰다:

Mahomedalid가 지적했듯이 cat이는 필수가 아니며 약간 중복되지만 깔끔하고 읽기 쉬운 명령을 만듭니다.

cat그것이 당신을 괴롭히는 경우 더 나은 해결책은 다음과 같습니다.

<textfile awk "20 <= NR && NR <= 45"

답변3

답변은 아니지만 댓글로 게시할 수는 없습니다.

또 다른 (매우 빠른) 방법은 다음과 같습니다.맥사이프 여기:

{ head -n 19 >/dev/null; head -n 26; } <infile

동일한 테스트 파일 사용여기그리고 동일한 프로세스에 대한 몇 가지 벤치마크는 다음과 같습니다(행 1000020-1000045 추출).

맥사이프:

{ head -n 1000019 >/dev/null; head -n 26; } <iplist

real    0m0.059s

스테판:

head iplist -n 1000045 | tail -n 26

real    0m0.054s

이것은 지금까지 가장 빠른 솔루션이며 차이는 무시할 수 있습니다.(단일 패스의 경우)(몇 개의 행, 수백만 개의 행 등 다양한 범위를 시도했습니다.)

그러나 파이프라인을 찾아야 하는 애플리케이션의 경우 파이프라인 없이 이를 수행하면 상당한 이점을 얻을 수 있습니다.여러 범위비슷한 방식으로 라인을 작성합니다. 예를 들면 다음과 같습니다.

for  pass in 0 1 2 3 4 5 6 7 8 9
do   printf "pass#$pass:\t"
     head -n99 >&3; head -n1
done <<1000LINES 3>/dev/null
$(seq 1000)
1000LINES

...인쇄...

pass#0: 100
pass#1: 200
pass#2: 300
pass#3: 400
pass#4: 500
pass#5: 600
pass#6: 700
pass#7: 800
pass#8: 900
pass#9: 1000

...파일을 한 번만 읽습니다.


// 다른 sed솔루션은 전체 파일을 읽는 데, 이는 대용량 파일에 관한 것이므로 awk그다지 perl효율적이지 않습니다. 지정된 범위의 마지막 행 뒤에 exit몇 가지 대안을 추가했습니다 .q

스테판:

awk "1000020 <= NR && NR <= 1000045" iplist

real    0m2.448s

그리고

awk "NR >= 1000020;NR==1000045{exit}" iplist

real    0m0.243s

데카그다르( sed):

sed -n 1000020,1000045p iplist

real    0m0.947s

그리고

sed '1,1000019d;1000045q' iplist

real    0m0.143s

스티븐 D:

perl -ne 'print if 1000020..1000045' iplist

real    0m2.041s

그리고

perl -ne 'print if $. >= 1000020; exit if $. >= 1000045;' iplist

real    0m0.369s

답변4

sed와 awk가 채택되었으므로 다음은 Perl 솔루션입니다.

perl -nle "print if ($. > 19 && $. < 46)" < textfile

또는 댓글에서 지적했듯이:

perl -ne 'print if 20..45' textfile

관련 정보