하지만 작동하지 않습니다!

하지만 작동하지 않습니다!

아래 목록에 표시된 것처럼 수천 개의 행이 있습니다.
파일명="텍스트 파일"

3 2 3 1 4 7
5 8 6 8 9 8
8 9 4 7 3 9 
2 3 4 4 9 2 
2 2 0 9 4 0 
0 9 8 2 4 0

조건을 사용하여 특정 요소(예: 다섯 번째 열)를 검색해야 합니다. (실제로 최대값을 찾아야 합니다.) 이 출력을 원합니다. 다섯 번째 열의 최대값 = 9

라인: 5 8 6 8 9 8

    2 3 4 4 9 2

다음 코드를 사용했습니다.

var=$(cat newfifth1 | awk 'BEGIN {max = 0} {if ($5>max) max = $5} END {print max}')
cat textfile | grep "$var" | cat $1 $2 $3 $4 $5 $6 >> newtextfile

하지만 작동하지 않습니다!

가능하다면 배열을 사용하는 더 쉬운 방법과 방법을 알려주십시오.

답변1

귀하의 질문에 있는 데이터 샘플에 따르면 이것이 귀하가 원하는 것 같습니다(그렇지 않으면 질문을 명확히 해주세요).

awk '$5 > max { max = $5 ; out = $0 } END { print out }' datafile

그러면 열 5에 최대값이 있는 데이터 파일의 행이 인쇄됩니다.

프로그램은 다음과 같이 작동합니다. 각 행에 대해 다섯 번째 열 요소를 max저장된 최대값(초기 0)과 비교하고, 더 큰 값이 발견되면 max할당된 값을 얻고(이후 비교를 위해) 현재 Row( $0) 변수에 저장된 최대값을 포함합니다 out. 프로그램의 마지막 작업으로 변수의 값이 out인쇄됩니다.

데이터에 0보다 작은 값만 있는 경우 ( max암묵적인 0 초기화로 인해) 약간의 확장이 필요합니다. 일반적으로 max해당 값보다 낮은 것으로 알려진 값으로 변수를 명시적으로 초기화하는 것으로 충분합니다. 예 를 들어 BEGIN { max = -999999 }다음과 같은 일반적인 코드 패턴을 사용할 수도 있습니다.

awk '(max==0 && max=="") || $5 > max { max = $5 ; out = $0 } END { print out }' datafile

(max==0 && max=="")조건 부분을 " max아직 정의되지 않았나요?"(즉, 아직 값이 할당되지 않음)로 해석합니다.

답변2

여기에는 몇 가지 해결책이 있습니다.

2회(무한 그룹):

awk '
    {
        if (NR == FNR) {
                if ($5 > max) max = $5
        } else {
                if ($5 == max) print
        }
    }' textfile textfile
  • NR모든 입력에서 계산된 레코드 번호(줄 번호)입니다.  FNR줄 번호입니다현재 파일 내에서. 따라서 예를 들어 3줄 길이의 와 4줄 길이의 awk2개 파일의 입력을 사용하여 실행하는 경우 다음 값이 사용됩니다.fileCfileDNRFNR

    NR    FNR
     1     1
     2     2
     3     3
     4     1
     5     2
     6     3
     7     4
    

    따라서 테스트는 NR == FNR첫 번째 파일이 표시되는지 확인하는 고전적인 방법입니다. 

  • 따라서 위의 내용은 입력 파일을 두 번 읽습니다(두 번 지정된 마지막 줄을 보셨나요 textfile?). 첫 번째 패스에서 최대값이 발견되면 두 번째 패스에서는 해당 값을 포함하는 모든 행을 인쇄합니다.

원샷(어레이 사용):

awk '
    {
        if ($5 >= max) {
                if ($5 > max) {
                        max = $5
                        delete result
                        count = 0
                }
                result[++count] = $0
        }
    }
END { for (i = 0; i <= count; i++) print result[i] }' textfile
  • 그러면 최대값과 일치하는 행이 라는 배열에 저장됩니다 result. 파일 읽기를 마칠 때까지(파일을 한 번만 읽기 때문에) 최대값을 알 수 없기 때문에 이는 까다롭습니다. 따라서 이전에 본 것보다 높은 값(즉, 새로운 최대값을 찾는 경우)을 만날 때마다 배열을 지우고( delete) 다시 시작합니다.result
  • 그런 다음 파일 끝에 도달하면 찾은 내용을 인쇄합니다.

참고: 다섯 번째 열의 모든 값이 0 이하이면 위 명령이 실패합니다. 이 상황을 처리하려면 "전체"( 테스트 포함) if ($5 >… 로 변경하세요.if (max == "" || $5 >…if ($5 >= max)

관련 정보