2016-12-03 4 views
3

나는AWK 파일의 기록을 마지막으로 두 번째를 인쇄

Words on 
many line 
% 
More Words 
on many lines 
% 
Even More Words 
on many lines 
% 

같은 설정 파일을하고 난 레코드가 각 후 %로 구분되는이 파일의 기록을 지속 할 두 번째 출력하고 싶습니다 텍스트 블록.

은 내가 사용하고 있습니다 :

awk -v RS=\% ' END{ print NR }' $f 

레코드의 수 (1136)를 찾을 수 있습니다. 그럼 난

awk -v RS=\% ' { print $(NR-1) }' $f 

awk -v RS=\% ' { print $(NR=1135) }' $f 

했다. 이들 중 어느 것도 작동하지 않고 대신 파일의 시작 부분과 빈 줄이 표시됩니다. 출력 :

"You know, of course, that the Tasmanians, who never committed adultery, are 
now extinct." 
    -- M. Somerset Maugham 


"The 
is 
what 
that 


이 출력이 많은, 더 많은 빈 줄이 있고 파일의 중간에 가까운 기록을 포함한다.

awk -v RS=\% 'END{ print $(NR-1) }' $f 

은 빈 줄을 반환합니다. $(NR-x) 값이 다른 동일한 명령도 공 i 행을 리턴합니다.

이 경우 마지막 기록에서 두 번째 기록까지 누가 도와 줄 수 있습니까? 감사합니다.

+1

'$ n'은 _field_을 선택합니다; _record_ (보통은 여기선이 아님)을 선택하려면 하나의 파일이나 결합 된 파일에 대해서는'awk -vRS = % 'NR == 1135'', 여러 파일들에 대해서는'FNR'을 사용하십시오. 'awk -vRS = % 'FNR == NR {sel = NR-1} FNR == sel'filename filename'과 같이 한 번에 두 패스를 모두 수행 할 수 있습니다. 그러나 두 개의 막대기로 @ dawg의 한 패스를 더 잘 사용하십시오. –

답변

3

당신이 할 수있는 단지 라인을 계산하는 경우,

awk '{a[NR]=$0} END{print a[NR-1]}' file 

를 또는 (또는 레코드 수)를 기반으로하면 롤링 삭제를 유지하여 메모리가 너무 많아지지 않습니다.

$ seq 999999 | tail -2 
999998 
999999 
$ seq 999999 | awk '{a[NR]=$0; delete a[NR-3]} END{print a[NR-1]}' 
999998 

텍스트 블록 인 경우 블록을 구분 된 레코드로 분리 할 수있는 경우 동일한 방법이 적용됩니다.당신은 할 수

$ echo "$txt" | awk -v RS=\% '{a[NR]=$0} END{print a[NR-1]}' 

Even More Words 
on many lines 

$ echo "$txt" | awk -v RS=\% '{a[NR]=$0} END{print a[NR-2]}' 

More Words 
on many lines 
당신이 선두를 인쇄 할하려면

및 후행 \n :

을 감안할 때 :

$ echo "$txt" 
Words on 
many line 
% 
More Words 
on many lines 
% 
Even More Words 
on many lines 
% 

은 당신이 할 수있는

$ echo "$txt" | awk 'BEGIN{RS="%\n"} {a[NR]=$0} END{printf a[NR-2]}' 
Words on 
many line 

을 마지막으로, 경우 인쇄하려는 특정 레코드를 알고 있다면 awk에서 다음과 같이하십시오.

당신이 임의의 기록을 원하는 경우
$ seq 999999 | awk -v mrk=1135 'NR==mrk{print; exit}' 
1135 

, 당신은 할 수있다 : 이것에 대한

$ awk -v min=1 -v max=1135 'BEGIN{srand() 
            RS="%\n" 
            tgt=int(min+rand()*(max-min+1)) 
            } 
          NR==tgt{print; exit}' file 
+0

이것은 가까워지고있는 것 같아요.하지만 레코드는 여러 줄로 구성 될 수 있습니다. 한 줄짜리 레코드와 한 줄에 100 줄짜리 레코드가 있습니다. – Angelo

+0

그냥 'RS'를 적절하게 설정하면 제대로 작동합니다 ... – dawg

+0

두 번째에서 마지막 레코드까지 대신 임의 레코드를 인쇄하려면 어떻게해야합니까? 즉, 1에서 1135 사이의 레코드를 출력 할 수 있습니까? – Angelo

1

해결책은 awk가 있어야합니까? 단지 머리와 꼬리를 사용하는 것이 더 간단합니다.

awk '{this=last;last=$0} END{print this}' file 

를 또는, 메모리에 전체 파일을 가지고 괜찮다면 :

tail -2 file.txt | head 1 > justthatline.txt 
+0

그게'꼬리 -2 file.txt되지 않을까요 | 머리 - n 1'? 이것은 창의적이지만'head '에 대한'-n' 인수가 없습니다. – dawg

+0

그들은 단일 행이 아니며 각 레코드의 행 수가 1 행에서 100 행까지 다양합니다. – Angelo

+0

'tac 파일은 어떻습니까? sed | tac' ... lol – EvansWinner

0

가장 좋은 방법은 BEGIN 구문을 사용하는 것입니다.

awk 'BEGIN{RS="%\n"; ORS="%\n"}(NR>=2){print}' file 

RS와 ORS는 각각 입력 파일과 출력 레코드 구분 기호를 설정합니다.