위와 아래 3단계의 값보다 최소 2배 큰 값을 동일한 열에 인쇄합니다.

위와 아래 3단계의 값보다 최소 2배 큰 값을 동일한 열에 인쇄합니다.

목록이 있어요

2
2
2
3
2
2
2
4
2
2
2

위와 아래의 3단계 값보다 최소 2배 더 큰 값을 동일한 열에 인쇄하고 싶습니다.

출력은

4

어떻게 하나요? 저도 비슷한 질문을 했어요여기, 더 잘 설명하기 위해 여기에 글을 쓰고 있습니다. 감사합니다.

20171006 업데이트: 실제 입력 파일을 지나치게 단순화해서 죄송합니다. 실제로는 목록이 아닌 테이블입니다. 여러 열(열 2, 3, 4 등) 중에서 선택하고 열 1을 인쇄해야 합니다. 해당 열에 대해 이와 같은 스크립트의 정보를 어떻게 병합합니까?

A 2 2 2
B 2 2 2
C 2 2 2
D 3 3 3
E 2 2 2
F 2 2 2
G 2 2 2
H 4 4 4
I 2 2 2 
J 2 2 2 
K 2 2 2 

그리고 얻다

H

답변1

에서 이 작업을 수행할 수 있습니다 awk. 세 번째 행과 마지막 행을 여섯 번째 행과 현재 행을 비교하려면 처음 6개 행을 저장해야 합니다. 이에 대한 일반적인 트릭은 보유하려는 행 수로 인덱스가 지정된 NR%6배열 인 링 버퍼를 사용하는 것입니다 6.

awk '
  NR > 6 {
    x = saved[NR%6]; y = saved[(NR - 3) % 6]; z = $0
    if (y >= 2*x && y >= 2*z) print y
  }
  {saved[NR % 6] = $0}'  < file

편집하려면: 비교할 키와 값을 저장하세요.

awk -v key=1 -v value=2 '
  NR > 6 {
    x = saved_value[NR%6]; y = saved_value[(NR - 3) % 6]; z = $value
    if (y >= 2*x && y >= 2*z) print saved_key[(NR - 3) % 6]
  }
  {saved_key[NR % 6] = $key; saved_value[NR % 6] = $value}'  < file

어디에 key인쇄할 열의 인덱스와 value비교할 값이 포함된 열이 있습니다.

또는 2, 3, 4열(예: 평균)을 기반으로 원하는 측정항목을 선택하세요.

awk '
  {metric = ($2 + $3 + $4) / 3}
  NR > 6 {
    x = saved_metric[NR%6]; y = saved_metric[(NR - 3) % 6]; z = $metric
    if (y >= 2*x && y >= 2*z) print saved_key[(NR - 3) % 6]
  }
  {saved_key[NR % 6] = $key; saved_metric[NR % 6] = $metric}'  < file

답변2

메모리의 전체 파일을 읽지 않고:

paste <(tail -n+4 file.txt | head -n-3) <(head -n-6 file.txt) <(tail -n+7 file.txt) |
    awk '$1 >= 2*$2 && $1 >= 2*$3 {print $1}'

<(...)이를 위해서는 구성(AT&T ksh또는 bash) 을 처리할 수 있는 셸 zshhead음수 오프셋을 지원하는 구현이 필요합니다.

설명하다:위의 명령은 paste현재 값, 3단계 위의 값, 3단계 아래의 값을 같은 줄에 넣고 awk2배 더 큰 조건을 확인합니다.

답변3

해결책:

awk 'function mean(sum){ 
          m=sum/3; return (int(m) == m)? m: int(m)+1 
     }
     { a[NR]=$0 }
     END{ 
         for(i=4;i<=NR-3;i++) 
             if (a[i]>=mean(a[i-3]+a[i-2]+a[i-1])*2 &&
                a[i]>=mean(a[i+3]+a[i+2]+a[i+1])*2) 
             print a[i] 
     }' file

  • a[NR]=$0- 모든 값을 a레코드 번호로 색인된 배열 로 수집NR

산출:

4

답변4

따라서 이를 수행하려면 3 + 1 + 3 입력 행의 슬라이딩 윈도우를 유지해야 합니다.

awk -vn=3 -va=2 'BEGIN { N=2*n+1 } { t=(NR-n)%N; m=NR%N; b=(NR+n)%N; w[b]=$0 } NR >= N && w[m] >= a*w[t] && w[m] >= a*w[b] { print w[m] }' file

n이렇게 하면 조건을 만족하는 모든 값이 인쇄되며, 명령줄에서 변수를 조정(변경)하여 거리를 쉽게 수정할 수 있고, -vn=3가중치를 변경(변경)하여 거리를 쉽게 수정할 수 있다는 추가 이점이 있습니다.a-va=2

이 코드는 마지막 N 값을 순환 버퍼에 저장합니다. 여기서 N은 2*n + 1 입니다 w. 중간 값이 버퍼의 첫 번째 값 ( "top"의 경우)의 배수와 버퍼의 마지막 값 ( "bottom"의 경우)의 배수 w[m]보다 크면 이를 인쇄합니다.aw[t]taw[b]b


공개된 스크립트 awk:

BEGIN   { N = 2*n + 1 }

        {
            t = (NR - n)%N
            m = NR%N
            b = (NR + n)%N
            w[b] = $0
        }

NR >= N && w[m] >= a*w[t] && w[m] >= a*w[b] { print w[m] }

관련 정보