개행을 기준으로 파일을 분할하고 분할 후 파일의 두 번째 필드만 가져오는 방법

개행을 기준으로 파일을 분할하고 분할 후 파일의 두 번째 필드만 가져오는 방법

아래 샘플 텍스트 파일:

#This is a sample file

## version 3.0 
- change 1 
- change 2

## version 2.5
- change 1
- change 2
- change 3

## version 2.4
- change 1
- change 2

아래와 같이 맨 위에 있는 파일의 최신 변경 사항 바로 뒤에 있습니다.

## version 3.0 
- change 1 
- change 2

다음 명령을 만들 수 있습니다.

awk -v RS= '{print > ("filename" NR ".txt")}' sample.txt

하지만 모든 파일을 만들고 싶지는 않습니다. 필요한 것을 얻는 데는 몇 분밖에 걸리지 않습니다.

답변1

awk를 사용하십시오.

$ awk -v RS= '/\n-/{print; exit}' sample.txt
## version 3.0
- change 1
- change 2

해당 출력을 파일로 리디렉션하기만 하면 질문의 코드에서와 같이 출력 파일을 생성하기 위해 awk가 하위 쉘을 생성하도록 할 이유가 없습니다. awk를 호출할 때 쉘에서 이 작업을 수행하도록 하십시오.

awk -v RS= '/\n-/{print; exit}' sample.txt > output.txt

충분하지 않은 경우 버전 블록을 기본 주석과 분리하는 데 필요한 것으로 /\n-/변경 하십시오./^## version/NR > 1/\n-/

답변2

나는 무엇을 할 것인가?ecord eparator로 구동 \n\n:RSgensub()

awk '
    BEGIN{RS="\n\n"}
    {
        v=gensub(/## version ([0-9\.]+)/, "\\1", "1")
        v=v+0      # numeric cast
        if (v > max) {
            max=v
            arr[v]=$0
        }
    }
    END{print arr[max]}
' file

## version 3.0 
- change 1 
- change 2

노트 블록은 입력의 어느 위치에나 위치할 수 있습니다. 솔루션은 블록의 순서에 의존하지 않습니다.

답변3

만약에허용됨(이식성):

perl -00 -ne '
    BEGIN{our $max = 0, %h}
    my ($v) = /## version ([\d\.]+)/;
    if ($v > $max) {$max=$v; $h{$v}=$_}
    END{print $h{$max}}
' file

블록은 입력의 어느 위치에나 위치할 수 있습니다.

관련 정보