파일에서 키 주위의 줄 추출

파일에서 키 주위의 줄 추출

약 1500만 줄의 큰 파일이 있습니다. 홀수 행에는 키(키뿐만 아니라)가 포함되며 심지어 행도 데이터입니다. 즉, 파일은 다음과 같습니다.

WRTZ Tyrosine
1287998798
ASDF Proline
9408654860
TYSR Serine
9809804090
ASDF Cytosine
4950409808

여기서 키는 ASDF, TYSR, 입니다 WRTZ.

약 100,000개의 키 목록이 있습니다. 이 키에 해당하는 데이터(2개 행)를 추출하고 싶습니다.

제가 시도한 한 가지 방법은 grep키가 포함된 행에서 행 번호를 가져온 다음 루프에서 및를 사용하여 head해당 행과 다음 행을 추출하는 것이었습니다. tail다만, 실행하는데 시간이 많이 걸릴 것 같습니다.

이를 수행하는 더 효율적인 방법이 있습니까?

답변1

짝수행과 홀수행에 변화가 없는 경우. 그런 다음 다음 명령을 사용해보십시오.

awk 'NR%2{printf $1"-";next;}1' <Filename>

위 명령의 출력은 다음과 같습니다.

WRTZ-1287998798

ASDF-9408654860

TYSR-9809804090

ASDF-4950409808

답변2

작은 awk 스크립트로 작업을 수행할 수 있습니다. awk man 매뉴얼을 읽어보면 이해하기 쉽습니다.

    #!/usr/bin/awk -f
    BEGIN{got=0;linenum=0}
    /ASDF/{printf ("%s ",$1); got=1;linenum=NR+1}
    /TYSR/{printf ("%s ",$1); got=1;linenum=NR+1}
    /WRTZ/{printf ("%s ",$1); got=1;linenum=NR+1}
    /^[0-9]/{if ( ( got == 1 ) && ( linenum == NR) ) {
    printf("%s\n",$1)
    got=0
    linenum=0
    }}

출력은 다음과 같습니다:

    ./awk_script data_file

    WRTZ 1287998798
    ASDF 9408654860
    TYSR 9809804090
    ASDF 4950409808

자신의 필요에 맞게 수정할 수 있습니다!

답변3

grep가장 원하는 것은 일치 항목 주위에 +/- 선을 표시하는 기본 옵션을 활용하는 것입니다 .

   Context Line Control
       -A NUM, --after-context=NUM
              Print NUM lines of trailing context after matching lines.  Places a line containing a group separator (--)  between  contiguous
              groups of matches.  With the -o or --only-matching option, this has no effect and a warning is given.

       -B NUM, --before-context=NUM
              Print  NUM  lines of leading context before matching lines.  Places a line containing a group separator (--) between contiguous
              groups of matches.  With the -o or --only-matching option, this has no effect and a warning is given.

       -C NUM, -NUM, --context=NUM
              Print NUM lines of output context.  Places a line containing a group separator (--) between contiguous groups of matches.  With
              the -o or --only-matching option, this has no effect and a warning is given.

답변4

사용행복하다(이전 Perl_6)

쌍을 이루는 라인을 찾고 있다면 다음을 수행 rotor하십시오 batch.

~$ raku -e '.put for lines.rotor(2, partial => True).map: *.words[0,2];'  file

#OR

~$ raku -e '.put for lines.batch(2).map: *.words[0,2];'  file

Raku의 rotor/ batch루틴은 사용자가 정의한 수(예: 23, 4 등)의 요소(예: lines)를 가져와 함께 그룹화할 수 있습니다. 완전한 쌍이 필요한 경우(즉, 파일에 짝수 줄이 포함되어 있는 경우) 간단히 rotorpartial => True매개변수를 사용하고 제거하면 됩니다.

참고: 이 코드는 공백으로 구분된 기준에 따라 .words요소를 유지합니다 . 예를 들어, 일부 쌍의 words첫 번째 행에 2개가 있고 다른 쌍의 첫 번째 행에 3개(또는 그 이상)가 있는 경우 words문제가 발생할 수 있습니다 .

첫 번째를 선택하면 word이 문제를 피할 수 있습니다.라인은 다음과 같습니다:

~$ raku -e '.put for lines.rotor(2).map( *.map: *.words[0]);'  file

#OR (using `>>` hyper notation):

~$ raku -e '.put for lines.rotor(2)>>.map: *.words[0];'  file

입력 예:

WRTZ Tyrosine
1287998798
ASDF Proline
9408654860
TYSR Serine
9809804090
ASDF Cytosine
4950409808

출력 예(모든 코드 예):

WRTZ 1287998798
ASDF 9408654860
TYSR 9809804090
ASDF 4950409808

https://docs.raku.org/routine/rotor
https://raku.org

관련 정보