programing

파일에서 n번째 줄을 가져오는 Bash 도구

yellowcard 2023. 4. 15. 08:41
반응형

파일에서 n번째 줄을 가져오는 Bash 도구

렇게논논논논논논논논논논논논? 쓰고 있어요.head -n | tail -1그런 것도 있지만 파일에서 특정 행(또는 행 범위)을 추출하는 Bash 툴이 있는지 궁금합니다.

'캐노닉'이란, 그것을 하는 것이 주된 기능인 프로그램을 말합니다.

head를 피우다tail추천할 수 있는 건sed음음음같 뭇매하다

sed 'NUMq;d' file

서 ★★★★★NUM를 들어, 인쇄하는 행의 번호입니다.예를 들어 다음과 같습니다.sed '10q;d' filefile.

설명:

NUMq회선번호가 다음과 같으면 즉시 종료됩니다.NUM.

d은, 「인쇄하지 않다」가 있기 때문입니다.이것은 마지막 행에서 금지됩니다.이것은, 다음의 이유로,q를 지정하면 종료 시 나머지 스크립트는 건너뛰게 됩니다.

「 」가 NUM변수에서는 단일 따옴표 대신 큰따옴표를 사용합니다.

sed "${NUM}q;d" file
sed -n '2p' < file.txt

두 번째 줄을 인쇄합니다.

sed -n '2011p' < file.txt

2011년 라인

sed -n '10,33p' < file.txt

10행부터 33행까지

sed -n '1p;3p' < file.txt

첫 번째 줄과 세 번째 줄

기타 등등...

sed를 사용하여 행을 추가하는 경우 다음을 확인할 수 있습니다.

sed: 특정 위치에 선을 삽입합니다.

이 페이지에서 제안하는 솔루션을 벤치마킹할 수 있는 독특한 상황이 있기 때문에 제안 솔루션의 통합으로 각 솔루션의 실행 시간을 포함하여 이 답변을 작성합니다.

세우다

3.261기가바이트 ASCII 텍스트 데이터 파일이 있으며 각 행에 키와 값의 쌍이 하나씩 있습니다.이 파일에는 총 3,339,550,320개의 행이 포함되어 있으며, Vim으로의 이동을 포함하여 지금까지 시도한 편집기에서 열 수 없습니다.500,000,000 행에서 시작하는 값 중 일부를 조사하려면 이 파일의 서브셋이 필요합니다.

파일에 행이 너무 많기 때문에:

  • 데이터로 유용한 작업을 수행하려면 행의 하위 집합만 추출해야 합니다.
  • 내가 관심 있는 가치까지 모든 행을 읽으려면 시간이 오래 걸릴 것이다.
  • 솔루션이 관심 있는 행을 지나쳐 나머지 파일을 계속 읽으면 거의 30억 개의 관련 없는 행을 읽는 데 시간을 낭비하고 필요 이상의 시간이 소요됩니다.

best-case-scenario는 파일 내의 다른 행을 읽지 않고 파일에서 한 줄만 추출하는 솔루션인데, Bash에서는 어떻게 해야 할지 생각나지 않습니다.

제 정신의 목적상, 저는 제 자신의 문제에 필요한 5억 행 전체를 읽으려고 하지 않을 것입니다.대신 3,339,550,320에서 행 50,000,000을 추출하려고 합니다(전체 파일을 읽는 데 필요한 시간보다 60배 더 오래 걸립니다).

저는 ㅇㅇㅇㅇㅇㅇㅇㅇㅇ를 쓸 예요.time각 명령어를 벤치마킹합니다.

베이스라인

어떻게 하는지 head tail★★★★★★★★★★★★★★★★★★:

$ time head -50000000 myfile.ascii | tail -1
pgm_icnt = 0

real    1m15.321s

5000만 행의 베이스라인은 00:01:15.321입니다.5억 행까지 직진하면 아마 12.5분 정도 걸릴 겁니다

인하.

이건 의심스럽지만 시도해 볼 만합니다.

$ time cut -f50000000 -d$'\n' myfile.ascii
pgm_icnt = 0

real    5m12.156s

이것은 00:05:12.156을 실행하는 데 소요되며, 이는 기준보다 훨씬 느립니다.정지하기 전에 파일 전체를 읽었는지, 최대 5000만 줄까지 읽었는지 알 수 없지만, 그렇다고 해서 이 문제에 대한 실행 가능한 해결책은 아닌 것 같습니다.

AWK

은 ★★★★★★★★★★★★★★★★★입니다.exit파일이 완전히 실행되기를 기다리지 않았기 때문입니다.

$ time awk 'NR == 50000000 {print; exit}' myfile.ascii
pgm_icnt = 0

real    1m16.583s

이 코드는 00:01:16.583에 실행되었으며, 이는 약 1초 느릴 뿐 기준선의 개선은 이루어지지 않았습니다.이 속도라면 exit 명령어를 제외했다면 전체 파일을 읽는 데 76분 정도 걸렸을 것입니다!

기존 Perl 솔루션도 실행했습니다.

$ time perl -wnl -e '$.== 50000000 && print && exit;' myfile.ascii
pgm_icnt = 0

real    1m13.146s

이 코드는 00:01:13.146에 실행되었으며, 이는 기준보다 약 2초 빠른 속도입니다.만약 5억을 전부 사용한다면 아마 12분 정도 걸릴 겁니다.

sed의

이 게시판의 상위 답변은 다음과 같습니다.

$ time sed "50000000q;d" myfile.ascii
pgm_icnt = 0

real    1m12.705s

이 코드는 00:01:12.705로 실행되었으며 이는 기준보다 3초 빠르고 Perl보다 0.4초 빠릅니다.500,000,000개의 행에서 풀로 실행했다면 아마 12분 정도 걸렸을 겁니다.

지도 파일

bash 3.1이 있기 때문에 맵 파일솔루션을 테스트할 수 없습니다.

결론

대부분것 head tail 기껏해야sed3%로 하다

)% = (runtime/baseline - 1) * 100)

행 50,000,000

  1. = 00:01:12.705(-00:00:02.616 = -3.47%)sed
  2. 00:01:13.199(-00:00:02.175=-2.89%)perl
  3. = + 00:01:15.321(+00:00:00.000 = +0.00%)head|tail
  4. = + 00:01:16.583(+00:00:01.262 = +1.68%)awk
  5. = + 00:05:12.199(+00:03:56.835 = +314.43%)cut

행 500,000,000

  1. 00:12:07.050(-00:00:26.160)sed
  2. 00:12:11.460(-00:00:21.750)perl
  3. 00:12:33.210(+00:00:00.000)head|tail
  4. 00:12:45.830(+00:00:12.620)awk
  5. 00:52:01.199(+00:40:31.650)cut

행 3,338,559,320

  1. 01:20:54.599(-00:03:05.327)sed
  2. 01:21:24.045(-00:02:25.227)perl
  3. 01:23:49.273(+00:00:00.000)head|tail
  4. 01:25:13.548(+00:02:35.735)awk
  5. 05:47:23.026(+04:24:26.246)cut

★★★★★★★★★★★★★★★★ awk 빠르다 빠르다.

awk 'NR == num_line' file

true일 은 " " " 입니다.awk다음 작업을 수행합니다.{print $0}.


대체 버전

만약 당신의 파일이 크다면, 당신은 그것을 사용하는 것이 좋습니다.exit필요한 행을 읽은 후.이를 통해 CPU 시간을 절약할 수 있습니다.

awk 'NR == num_line {print; exit}' file

bash 변수에서 회선 번호를 지정할 경우 다음을 사용할 수 있습니다.

awk 'NR == n' n=$num file
awk -v n=$num 'NR == n' file   # equivalent

「시간 절약」을하면, 어느 할 수 있는지를 알 수 .exit특히 행이 파일의 첫 번째 부분에 있는 경우:

# Let's create a 10M lines file
for ((i=0; i<100000; i++)); do echo "bla bla"; done > 100Klines
for ((i=0; i<100; i++)); do cat 100Klines; done > 10Mlines

$ time awk 'NR == 1234567 {print}' 10Mlines
bla bla

real    0m1.303s
user    0m1.246s
sys 0m0.042s
$ time awk 'NR == 1234567 {print; exit}' 10Mlines
bla bla

real    0m0.198s
user    0m0.178s
sys 0m0.013s

따라서 0.198s와 1.303s의 차이는 약 6배 빨라집니다.

제 테스트에 따르면 성능과 가독성 측면에서 제가 권장하는 바는 다음과 같습니다.

tail -n+N | head -1

N원하는 회선 번호입니다.를 들어, 「」라고 하는 것은,tail -n+7 input.txt | head -17번으로 하다

tail -n+N 、 will will 、 ★★★★★★★★★★★★★★★★★★★★★★★★」N , , , , 입니다.head -1네.


다른 방법은head -N | tail -1을 사용하다7시, 7시, 7시

head -7 input.txt | tail -1

퍼포먼스에 관해서는 작은 사이즈에 큰 차이는 없지만 퍼포먼스에서는tail | head( ( ( ( ( ( ( ( (

많이 투표된 '1'sed 'NUMq;d'흥미롭지만, 저는 이것이 머리/꼬리 솔루션보다 더 적은 수의 사람들에게 이해되고 꼬리/머리보다 더 느리다고 주장합니다.

버전이 out헤헤헤헤/performedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformedperformed를 능가했습니다.sed 'NUMq;d'합니다.그것은 게시된 다른 벤치마크와 일치한다.꼬리/앞면이 정말 나빴던 경우는 찾기 어렵다.또한 이러한 작업은 최신 Unix 시스템에서 크게 최적화될 것으로 예상되는 작업이기 때문에 놀라운 일도 아닙니다.

퍼포먼스 차이에 대해 알기 위해 대용량 파일에 대해 다음과 같은 수치를 얻을 수 있습니다(9.3).G) :

  • tail -n+N | head -1: 3.7초
  • head -N | tail -1: 4.6초
  • sed Nq;d: 18.8인치

다를 수 는 다르다head | tail ★★★★★★★★★★★★★★★★★」tail | head입력이 경우와 가 됩니다.또, 「입력량이 작은 경우」라고 하는 경우도 있습니다sed(5일)

벤치마크를 재현하기 위해 다음을 시도할 수 있지만 현재 작업 디렉토리에 9.3G 파일이 작성된다는 점에 유의하십시오.

#!/bin/bash
readonly file=tmp-input.txt
readonly size=1000000000
readonly pos=500000000
readonly retries=3

seq 1 $size > $file
echo "*** head -N | tail -1 ***"
for i in $(seq 1 $retries) ; do
    time head "-$pos" $file | tail -1
done
echo "-------------------------"
echo
echo "*** tail -n+N | head -1 ***"
echo

seq 1 $size > $file
ls -alhg $file
for i in $(seq 1 $retries) ; do
    time tail -n+$pos $file | head -1
done
echo "-------------------------"
echo
echo "*** sed Nq;d ***"
echo

seq 1 $size > $file
ls -alhg $file
for i in $(seq 1 $retries) ; do
    time sed $pos'q;d' $file
done
/bin/rm $file

다음은 내 컴퓨터에서 실행한 결과입니다(SSD 및 16G 메모리가 장착된 ThinkPad X1 Carbon).최종 실행에서는 모든 것이 디스크가 아닌 캐시에서 나올 것으로 예상됩니다.

*** head -N | tail -1 ***
500000000

real    0m9,800s
user    0m7,328s
sys     0m4,081s
500000000

real    0m4,231s
user    0m5,415s
sys     0m2,789s
500000000

real    0m4,636s
user    0m5,935s
sys     0m2,684s
-------------------------

*** tail -n+N | head -1 ***

-rw-r--r-- 1 phil 9,3G Jan 19 19:49 tmp-input.txt
500000000

real    0m6,452s
user    0m3,367s
sys     0m1,498s
500000000

real    0m3,890s
user    0m2,921s
sys     0m0,952s
500000000

real    0m3,763s
user    0m3,004s
sys     0m0,760s
-------------------------

*** sed Nq;d ***

-rw-r--r-- 1 phil 9,3G Jan 19 19:50 tmp-input.txt
500000000

real    0m23,675s
user    0m21,557s
sys     0m1,523s
500000000

real    0m20,328s
user    0m18,971s
sys     0m1,308s
500000000

real    0m19,835s
user    0m18,830s
sys     0m1,004s

와, 모든 가능성!

이것을 시험해 보세요.

sed -n "${lineNum}p" $file

또는 Awk 버전에 따라 다음 중 하나를 선택합니다.

awk  -vlineNum=$lineNum 'NR == lineNum {print $0}' $file
awk -v lineNum=4 '{if (NR == lineNum) {print $0}}' $file
awk '{if (NR == lineNum) {print $0}}' lineNum=$lineNum $file

(또는 명령어를 사용해야 할 수 있습니다).

그라라 출력 력력 ?? ???표준 툴이 아닙니다. ★★★★★★★★★★★★★★.sed아마 가장 가깝고 사용하기 쉬울 겁니다.

두 개의 키 입력을 저장하고 괄호를 사용하지 않고 N번째 줄을 인쇄합니다.

sed  -n  Np  <fileName>
      ^   ^
       \   \___ 'p' for printing
        \______ '-n' for not printing by default 

예를 들어, 100번째 줄을 인쇄하려면:

sed -n 100p foo.txt      

Bash라는 태그가 이 에는 Bash의Bash의 사용법은 Bash(44) ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.사용법mapfile-s 및 (기호) »-n option (count) 。

가 있는 는, 「」42행째를 합니다.file:

mapfile -s 41 -n 1 ary < file

에서 어레이가 aryfile-s 41줄 (읽을 수 있습니다-n 142번입니다.쇄쇄: :

printf '%s' "${ary[0]}"

행의 범위가 필요한 경우는, 42~666 의 범위(포함)로 해, 직접 계산하지 않고, stdout 에 인쇄합니다.

mapfile -s $((42-1)) -n $((666-42+1)) ary < file
printf '%s' "${ary[@]}"

이 라인도 처리해야 하는 경우, 후행의 새 라인을 저장하는 것은 그다지 편리하지 않습니다.는 '어울리다'를 사용하세요.-t옵션(필수):

mapfile -t -s $((42-1)) -n $((666-42+1)) ary < file
# do stuff
printf '%s\n' "${ary[@]}"

다음과 같은 기능을 사용할 수 있습니다.

print_file_range() {
    # $1-$2 is the range of file $3 to be printed to stdout
    local ary
    mapfile -s $(($1-1)) -n $(($2-$1+1)) ary < "$3"
    printf '%s' "${ary[@]}"
}

외부 명령어는 없고 Bash만 내장되어 있습니다!

sed print를 사용하여 종료할 수도 있습니다.

sed -n '10{p;q;}' file   # print line 10

여기에는 Perl을 사용할 수도 있습니다.

perl -wnl -e '$.== NUM && print && exit;' some.file

Caffe Connoisser의 매우 유용한 벤치마크 답변의 후속으로...mapfile은 테스트되지 않았기 때문에 얼마나 빠른지 궁금해서 bash 4를 가지고 있기 때문에 스스로 빠르고 더러운 속도 비교를 해보았습니다.사람들이 칭찬하고 있는 가운데, 톱 답글의 코멘트 중 하나에 기재되어 있는 「머리 | 꼬리」법(머리 | 꼬리보다.사용된 테스트 파일 크기에 가까운 것은 없습니다.즉각 14M의 혈통 파일(공백으로 구분된 긴 행, 12000줄 미만)을 찾을 수 있었습니다.

숏버전: 맵파일은 컷메서드보다 빨리 표시되지만 다른 모든 방법보다 느리기 때문에 dud. tail |head, OTOH가 가장 빠를 것 같습니다만, 이 사이즈의 파일은 sed와 비교하면 그다지 큰 차이는 없습니다.

$ time head -11000 [filename] | tail -1
[output redacted]

real    0m0.117s

$ time cut -f11000 -d$'\n' [filename]
[output redacted]

real    0m1.081s

$ time awk 'NR == 11000 {print; exit}' [filename]
[output redacted]

real    0m0.058s

$ time perl -wnl -e '$.== 11000 && print && exit;' [filename]
[output redacted]

real    0m0.085s

$ time sed "11000q;d" [filename]
[output redacted]

real    0m0.031s

$ time (mapfile -s 11000 -n 1 ary < [filename]; echo ${ary[0]})
[output redacted]

real    0m0.309s

$ time tail -n+11000 [filename] | head -n1
[output redacted]

real    0m0.028s

이게 도움이 됐으면 좋겠네요!

대용량 파일의 가장 빠른 솔루션은 항상 tail|head입니다.단, 다음 두 가지 거리가 있습니다.

  • 파일의 시작부터 시작선까지를 지정합니다.라고 하자. lets lets lets lets lets lets lets lets lets letsS
  • 파일의 마지막 줄부터 마지막 줄까지의 거리.E

알려져 있습니다.그러면 다음과 같이 사용할 수 있습니다.

mycount="$E"; (( E > S )) && mycount="+$S"
howmany="$(( endline - startline + 1 ))"
tail -n "$mycount"| head -n "$howmany"

필요한 행의 개수만 몇 개입니까?

자세한 것은, https://unix.stackexchange.com/a/216614/79743 를 참조해 주세요.

위의 답변은 모두 질문에 직접 답변합니다.하지만 여기 덜 직접적인 해결책이 있습니다. 하지만 잠재적으로 더 중요한 아이디어가 있습니다. 생각을 불러일으키기 위해서죠.

행 길이는 임의이므로 n번째 행 에 있는 파일의 모든 바이트를 읽어야 합니다.대용량 파일이 있거나 이 작업을 여러 번 반복해야 하는 경우, 이 프로세스에 시간이 많이 걸리는 경우 데이터를 다른 방식으로 저장해야 하는지 심각하게 고려해야 합니다.

실제 해결책은 예를 들어 파일 시작 부분에 행이 시작되는 위치를 나타내는 인덱스를 갖는 것입니다.데이터베이스 형식을 사용하거나 파일 시작 부분에 테이블을 추가할 수 있습니다.또는 큰 텍스트 파일과 함께 별도의 인덱스 파일을 만들 수도 있습니다.

예를 들어, 줄 바꿈에 대한 문자 위치 목록을 작성할 수 있습니다.

awk 'BEGIN{c=0;print(c)}{c+=length()+1;print(c+1)}' file.txt > file.idx

.tail는 「」입니다seek파일 내의 적절한 포인트로 직접 이동합니다.

예: 라인 1000을 얻으려면:

tail -c +$(awk 'NR=1000' file.idx) file.txt | head -1
  • awk는 "문자 인식"이지만 tail은 "문자 인식"이 아니기 때문에 2바이트/멀티바이트 문자에서는 작동하지 않을 수 있습니다.
  • 대용량 파일에 대해 테스트해 본 적이 없습니다.
  • 답변도 참조해 주세요.
  • 또는 파일을 더 작은 파일로 분할합니다!

\n(통상은 새로운 행)으로 구분하여 여러 행을 취득한 경우.'컷'도 사용할 수 있습니다.

echo "$data" | cut -f2 -d$'\n'

파일에서 두 번째 줄이 나옵니다. -f3세 번째 줄입니다.

다른 사람이 말한 것을 사용하여, 저는 이것이 제 bash 쉘에 빠르고 댄디한 기능이 되길 바랐습니다.

을 만듭니다.~/.functions

내용을 추가합니다.

getline() { line=$1 sed $line'q;d' $2 }

이것을 의 '마음껏'에하세요.~/.bash_profile:

source ~/.functions

새로운 bash 창을 열면 다음과 같이 함수를 호출할 수 있습니다.

getline 441 myfile.txt

벌써 좋은 답변들이 많네요.아욱하다bash를 을 bash에 합니다.~/.bash_profile그리고 다음 로그인 시(또는 이 업데이트 후 .bash_profile을 원본으로 하는 경우)에는 파일을 파이프로 연결하기 위한 새로운 nifty "nth" 함수를 사용할 수 있습니다.

bash를 하는 경우)에bash를 다시 ( bash_profile(bash) 실행).source ~/.bach_profile)

# print just the nth piped in line
nth () { awk -vlnum=${1} 'NR==lnum {print; exit}'; } 

그런 다음 파이프로 연결하기만 하면 됩니다. 예:

$ yes line | cat -n | nth 5
     5  line

변수가 있는 sed를 라인 번호로 사용하여 n번째 행을 인쇄하려면:

a=4
sed -e $a'q:d' file

여기서 '-e' 플래그는 실행할 명령어에 스크립트를 추가하기 위한 것입니다.

상위 답변벤치마크살펴본 후 다음과 같은 작은 도우미 기능을 구현했습니다.

function nth {
    if (( ${#} < 1 || ${#} > 2 )); then
        echo -e "usage: $0 \e[4mline\e[0m [\e[4mfile\e[0m]"
        return 1
    fi
    if (( ${#} > 1 )); then
        sed "$1q;d" $2
    else
        sed "$1q;d"
    fi
}

기본적으로 다음 두 가지 방법으로 사용할 수 있습니다.

nth 42 myfile.txt
do_stuff | nth 42

이것은 bash 솔루션이 아닙니다만, 톱의 선택이 제 요구를 만족시키지 못한다는 것을 알았습니다.예를 들어,

sed 'NUMq;d' file

충분히 빨랐지만, 몇 시간 동안이나 매달려 있었고, 진척에 대해서는 아무 말도 하지 않았습니다.이 cpp 프로그램을 컴파일하여 원하는 행을 찾을 것을 권장합니다. 해서 할 수 있습니다.g++ main.cppmain.cpp를 사용하다.O.O.O.O.O.O.O.O.와 함께 실행했습니다./a.out

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int main() {
    string filename;
    cout << "Enter filename ";
    cin >> filename;

    int needed_row_number;
    cout << "Enter row number ";
    cin >> needed_row_number;

    int progress_line_count;
    cout << "Enter at which every number of rows to monitor progress ";
    cin >> progress_line_count;

    char ch;
    int row_counter = 1;
    fstream fin(filename, fstream::in);
    while (fin >> noskipws >> ch) {
        int ch_int = (int) ch;
        if (row_counter == needed_row_number) {
            cout << ch;
        }
        if (ch_int == 10) {
            if (row_counter == needed_row_number) {
                return 0;
            }
            row_counter++;
            if (row_counter % progress_line_count == 0) {
                cout << "Progress: line " << row_counter << endl;
            }
        }

    }
    return 0;
}

n번째 줄(단일 줄)을 얻는 방법

bash를 처리하지 않고 나중에 커스터마이즈할 수 있는 것이 필요한 경우 이 c 프로그램을 컴파일하여 커스텀바이너리 디렉토리에 바이너리를 드롭할 수 있습니다.따라서 .bashrc 파일을 편집하는 방법을 알고 있다고 가정합니다(경로 변수를 편집하는 경우에만 해당).모르는 경우 이 링크가 도움이 됩니다.

이 코드를 실행하려면 를 사용합니다(바이너리 이름을 "라인"으로 지정한 경우).

line [target line] [target file]

line 2 somefile.txt

코드:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char* argv[]){

  if(argc != 3){
      fprintf(stderr, "line needs a line number and a file name");
      exit(0);     
  }

  int lineNumber = atoi(argv[1]); 
  int counter = 0; 
  char *fileName = argv[2];

  FILE *fileReader = fopen(fileName, "r");
  if(fileReader == NULL){
      fprintf(stderr, "Failed to open file"); 
      exit(0); 
  }

  size_t lineSize = 0;
  char* line = NULL;

  while(counter < lineNumber){
     getline(&line, &linesize, fileReader);
     counter++
  }

  getline(&line, &lineSize, fileReader);

  printf("%s\n", line);     

  fclose(fileReader); 
  return 0; 
}

EDIT: fseek를 제거하고 while loop으로 교체합니다.

중 몇 bash 이 스크립트는 에 넣을 수 .이 스크립트는 다음과 같은 파일에 넣을 수 있습니다.get.sh 링크에 접속합니다./usr/local/bin/get(무엇보다)

#!/bin/bash
if [ "${1}" == "" ]; then
    echo "error: blank line number";
    exit 1
fi
re='^[0-9]+$'
if ! [[ $1 =~ $re ]] ; then
    echo "error: line number arg not a number";
    exit 1
fi
if [ "${2}" == "" ]; then
    echo "error: blank file name";
    exit 1
fi
sed "${1}q;d" $2;
exit 0

실행 가능 여부 확인

$ chmod +x get

하여 크크에서 할 수 .PATH 함께

$ ln -s get.sh /usr/local/bin/get

UPDATE 1 : 에서 훨씬 빠른 메서드가 발견되었습니다.awk

  • 5.353초 만에 위의 행을 얻을 수 있습니다.
rownum='133668997'; ( time ( pvE0 < ~/master_primelist_18a.txt |

LC_ALL=C mawk2 -F'^$' -v \_="${rownum}" -- '!_{exit}!--_' ) )
in0: 5.45GiB 0:00:05 [1.02GiB/s] [1.02GiB/s] [======> ] 71%            
     ( pvE 0.1 in0 < ~/master_primelist_18a.txt | 
     LC_ALL=C mawk2 -F'^$' -v  -- ; )  5.01s user 

1.21s system 116% cpu 5.353 total

77.37219=195591955519519519559551=0x296B0FA7D668C4A64F7F=

===============================================

는 '이해하다'라는 를 제기하고 perlawk:

제가 두 .7.58 GB-

가 드린 것도 있어요.perl 번호의 메커니즘(있는 인 속도 수 .행 번호의 하드 코드와 같은 2번째 코드도 있기 때문에 OS 캐싱 메커니즘(있는 경우)에서 잠재적인 속도 향상을 얻을 수 있습니다.

 f="$( grealpath -ePq  ~/master_primelist_18a.txt )"
 rownum='133668997'
 fg;fg; pv < "${f}" | gwc -lcm 
 echo; sleep 2; 
 echo; 
 ( time ( pv -i 0.1 -cN in0 < "${f}" | 
        
    LC_ALL=C mawk2 '_{exit}_=NR==+__' FS='^$' __="${rownum}" 

 ) ) | mawk 'BEGIN { print } END { print _ } NR' 
 sleep 2
 ( time ( pv -i 0.1 -cN in0 < "${f}" | 

    LC_ALL=C perl -wnl -e '$.== 133668997 && print && exit;' 

 ) ) | mawk 'BEGIN { print }  END { print _ } NR' ;

fg: no current job
fg: no current job
7.58GiB 0:00:28 [ 275MiB/s] [============>] 100%
        
148,110,134 8,134,435,629 8,134,435,629   <<<< rows, chars, and bytes 
                                               count as reported by gnu-wc



      in0: 5.45GiB 0:00:07 [ 701MiB/s] [=> ] 71%            
( pv -i 0.1 -cN in0 < "${f}" | LC_ALL=C mawk2 '_{exit}_=NR==+__' FS='^$' ; )  
   6.22s user 2.56s system 110% cpu 7.966 total
   77.37219=195591955519519519559551=0x296B0FA7D668C4A64F7F=


      in0: 5.45GiB 0:00:17 [ 328MiB/s] [=> ] 71%            
( pv -i 0.1 -cN in0 < "${f}" | LC_ALL=C perl -wnl -e ; )  
   14.22s user 3.31s system 103% cpu 17.014 total
   77.37219=195591955519519519559551=0x296B0FA7D668C4A64F7F=

은 '하다'로 할 수 요.perl 5.36또는 심지어perl-6것다 되어 있지 않지만 것 같으면(둘 다 설치되어 있지 않습니다).

7.966 secs (mawk2) vs. 17.014 secs (perl 5.34)

어느 이 확실히 이 더 알 수 것 .ASCIIfiles.complete files files files files files files files files.

This is perl 5, version 34, subversion 0 (v5.34.0) built for darwin-thread-multi-2level

Copyright 1987-2021, Larry Wall


mawk 1.9.9.6, 21 Aug 2016, Copyright Michael D. Brennan

언급URL : https://stackoverflow.com/questions/6022384/bash-tool-to-get-nth-line-from-a-file

반응형