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

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

나한테 테이블이 있어

A 1
A 1
A 1
A 1
A 1
A 1
A 2
B 1
B 1
B 1
B 2
B 1
B 1
B 1

열 2의 값이 같은 열에서 위의 3단계와 아래의 3단계보다 최소 2배 큰 열 1의 행을 인쇄하고 싶습니다.그러나 열 1에서 동일한 이름을 가진 행만 고려됩니다.

따라서 출력은 다음과 같아야 합니다.

B

위에서 굵게 표시된 추가 요구 사항을 충족하기 위해 Stéphane Chazelas가 작성한 이 스크립트를 수정하고 싶습니다.

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

(실제로 계속되는 포스팅입니다여기. 상황이 복잡하기 때문에 여기서는 더 잘 설명하고 싶습니다. )

. . .

20171010 업데이트:

현재 Stéphane Chazelas가 작성한 스크립트를 수정하고 있는데, 이제 내가 선택한 행의 값은 다음과 같습니다.위의 세 번째 값과 아래의 세 번째 값보다 최소 2배 작습니다.. 예전에는 제가 직접 이해하고 스크립트를 수정하려고 예제를 단순화했는데 v2 <= v1/2 && v2 <= v3/2또 실패했어요... 좀 더 쉽게 설명하기 위해 이제 다음과 같이 실제 파일을 제공하는데, 여기서 두 번째 열의 값은 쓸모가 없고,세 번째 열의 값을 비교합니다:

K00188:14:H2LMFBBXX:6:1101:27440:1668   1   2
K00188:14:H2LMFBBXX:6:1101:27440:1668   2   2
K00188:14:H2LMFBBXX:6:1101:27440:1668   3   2
K00188:14:H2LMFBBXX:6:1101:27440:1668   4   1
K00188:14:H2LMFBBXX:6:1101:27440:1668   5   1
K00188:14:H2LMFBBXX:6:1101:27440:1668   6   1
K00188:14:H2LMFBBXX:6:1101:27440:1668   7   1
K00188:14:H2LMFBBXX:6:1101:27440:1668   8   1
K00188:14:H2LMFBBXX:6:1101:27440:1668   9   1
K00188:14:H2LMFBBXX:6:1101:27440:1668   10  1
K00188:14:H2LMFBBXX:6:1101:6501:1686    1   2
K00188:14:H2LMFBBXX:6:1101:6501:1686    2   2
K00188:14:H2LMFBBXX:6:1101:6501:1686    3   2
K00188:14:H2LMFBBXX:6:1101:6501:1686    4   1
K00188:14:H2LMFBBXX:6:1101:6501:1686    5   1
K00188:14:H2LMFBBXX:6:1101:6501:1686    6   1
K00188:14:H2LMFBBXX:6:1101:6501:1686    7   2
K00188:14:H2LMFBBXX:6:1101:6501:1686    8   2
K00188:14:H2LMFBBXX:6:1101:6501:1686    9   2
K00188:14:H2LMFBBXX:6:1101:6501:1686    10  2

전체 줄을 인쇄하면 예상되는 출력은 다음과 같습니다.

K00188:14:H2LMFBBXX:6:1101:6501:1686    4   1
K00188:14:H2LMFBBXX:6:1101:6501:1686    5   1
K00188:14:H2LMFBBXX:6:1101:6501:1686    6   1

이것은 내 실패한 수정 사항입니다.

awk -v key=1 -v value=3 '
  NR > 6 {
    k1 = saved_key[NR%6];   k2 = saved_key[(NR - 3) % 6];   k3 = $key
    v1 = saved_value[NR%6]; v2 = saved_value[(NR - 3) % 6]; v3 = $value
    if (k1 == k2 && k2 == k3 && v2 <= v1/2 && v2 <= v3/2) print $0
  }
  {saved_key[NR % 6] = $key; saved_value[NR % 6] = $value}' < test

어떻게 수정할 수 있나요?

. . .

20171011 업데이트:

추가 키를 추가하려면 어떻게 해야 하나요?3열의 값을 4열 위와 아래의 세 번째 값(즉, 다른 열)과 비교합니다.? 20171011 업데이트를 참고하세요. 다시 한 번 감사드립니다!

K00188:14:H2LMFBBXX:6:1101:27440:1668   1   0   2
K00188:14:H2LMFBBXX:6:1101:27440:1668   2   0   2
K00188:14:H2LMFBBXX:6:1101:27440:1668   3   0   2
K00188:14:H2LMFBBXX:6:1101:27440:1668   4   1   0
K00188:14:H2LMFBBXX:6:1101:27440:1668   5   1   0
K00188:14:H2LMFBBXX:6:1101:27440:1668   6   1   0
K00188:14:H2LMFBBXX:6:1101:27440:1668   7   1   0
K00188:14:H2LMFBBXX:6:1101:27440:1668   8   1   0
K00188:14:H2LMFBBXX:6:1101:27440:1668   9   1   0
K00188:14:H2LMFBBXX:6:1101:27440:1668   10  1   0
K00188:14:H2LMFBBXX:6:1101:6501:1686    1   0   2
K00188:14:H2LMFBBXX:6:1101:6501:1686    2   0   2
K00188:14:H2LMFBBXX:6:1101:6501:1686    3   0   2
K00188:14:H2LMFBBXX:6:1101:6501:1686    4   1   0
K00188:14:H2LMFBBXX:6:1101:6501:1686    5   1   0
K00188:14:H2LMFBBXX:6:1101:6501:1686    6   1   0
K00188:14:H2LMFBBXX:6:1101:6501:1686    7   0   2
K00188:14:H2LMFBBXX:6:1101:6501:1686    8   0   2
K00188:14:H2LMFBBXX:6:1101:6501:1686    9   0   2
K00188:14:H2LMFBBXX:6:1101:6501:1686    10  0   2

전체 줄을 인쇄하면 예상되는 출력은 다음과 같습니다.

K00188:14:H2LMFBBXX:6:1101:6501:1686    4   1   0
K00188:14:H2LMFBBXX:6:1101:6501:1686    5   1   0
K00188:14:H2LMFBBXX:6:1101:6501:1686    6   1   0

이것은 나의 재판입니다:

awk -v key1=1 -v key2=2 -v value1=3 -v value2=4 '
    {
    k1 = saved_key1[NR%6];   k2 = saved_key1[(NR - 3) % 6];   k3 = $key1
    k4 = saved_key2[NR%6];   k5 = saved_key2[(NR - 3) % 6];   k6 = $key2
    v1 = saved_value1[NR%6]; v2 = saved_value1[(NR - 3) % 6]; v3 = $value1
    v4 = saved_value2[NR%6]; v5 = saved_value2[(NR - 3) % 6]; v6 = $value2
    if (k1 == k2 && k2 == k3 && v2 <= v4/2 && v2 <= v6/2) print saved_record[(NR-3)%6]
  }
  {saved_key1[NR % 6] = $key1; saved_value1[NR % 6] = $value1}' < file

답변1

그러면 다음과 같습니다:

awk -v key=1 -v value=2 '
  NR > 6 { # for 7th record and over only
    k1 = saved_key[NR%6];   k2 = saved_key[(NR - 3) % 6];   k3 = $key
    v1 = saved_value[NR%6]; v2 = saved_value[(NR - 3) % 6]; v3 = $value
    if (k1 == k2 && k2 == k3 && v2 >= 2*v1 && v2 >= 2*v3) print k2
  }
  # for every record, save key and value in ring buffers:
  {saved_key[NR % 6] = $key; saved_value[NR % 6] = $value}'

AND의 비교 는 k1 == k2값이 숫자처럼 보이는 경우(따라서 와 동일한 것으로 간주됨) 숫자로 비교되고, 그렇지 않으면 텍스트로 비교됩니다. 텍스트 비교를 강제하도록 변경되었습니다.k2 == k3000k1 "" == k2

또는 전체 기록을 저장하고 검사 중에 다시 분할할 수도 있습니다. 너 같이20171010 업데이트:

awk -v key=1 -v value=3 '
  NR > 6 {
    # "above" is an array with the fields of 6th last record
    split(saved_record[NR%6], above)
    # "text" is the 3rd last record and the one we will be looking at
    text = saved_record[(NR - 3) % 6]
    # "text" fields split into the "here" array.
    split(text, here)
    # $0 contains the current record (the one 3 lines below "here")
    # and $1, $2, $3... the fields of that record.
    if (above[key] == here[key] && here[key] == $key && \
        here[value] <= above[value] / 2 && here[value] <= $value / 2)
      print text
  }
  {saved_record[NR % 6] = $0}'

답변2

GNU는 상대적으로 짧습니다.datamash+awk해결책:

datamash -W -g1 count 2 collapse 2 <file | awk '$2==7{ split($3,a,","); k=a[4]; 
             delete a[4]; if(k>=a[7]*2) print $1 }'

관련 정보