awk 시리즈 에 정통 (20): awk 배열 용법 상세 설명

10851 단어
돌아 가기:
  • Linux 시리즈 글
  • Shell 시리즈 글
  • Awk 시리즈 글
  • 배열
    awk 배열 특성:
  • awk 의 배열 은 관련 배열 (즉, key/value 방식 의 hash 데이터 구조) 이 고 색인 아래 표 시 는 수치 (심지어 음수, 소수 등) 일 수도 있 으 며 문자열 일 수도 있 습 니 다.
  • 내부 에서 awk 배열 의 색인 은 모두 문자열 입 니 다. 수치 색인 을 사용 할 때 내부 에서 도 문자열
  • 으로 변 환 됩 니 다.
  • awk 의 배열 요소 의 순서 와 요소 가 삽 입 될 때의 순 서 는 다 를 수 있 습 니 다.
  • awk 배열 지원 배열
  • awk 접근, 할당 배열 요소
    arr[idx]
    arr[idx] = value
    

    색인 은 정수, 음수, 0, 소수, 문자열 일 수 있 습 니 다.수치 인덱스 라면 CONVFMT 변수 가 지정 한 형식 에 따라 문자열 로 먼저 변환 합 니 다.
    예 를 들 면:
    awk '
      BEGIN{
        arr[1]   = 11
        arr["1"] = 111
        arr["a"] = "aa"
        arr[-1]  = -11
        arr[4.3] = 4.33
    #         :www.junmajinlong.com
        print arr[1]     # 111
        print arr["1"]   # 111
        print arr["a"]   # aa
        print arr[-1]    # -11
        print arr[4.3]   # 4.33
      }
    '
    

    배열 에 존재 하지 않 는 요 소 를 색인 으로 접근 할 때 빈 문자열 을 되 돌려 주 고 이 요 소 를 만 들 고 값 을 빈 문자열 로 설정 합 니 다.
    awk '
      BEGIN{
        arr[-1]=3;
        print length(arr);  # 1
        print arr[1];
        print length(arr)   # 2
      }'
    

    awk 배열 길이
    awk 는 length() 함 수 를 제공 하여 배열 의 요소 개 수 를 가 져 옵 니 다. 문자열 의 문자 수 를 가 져 올 수도 있 습 니 다.문자열 로 변 환 된 문자 의 수 를 가 져 올 수 있 습 니 다.
    awk 'BEGIN{arr[1]=1;arr[2]=2;print length(arr);print length("hello")}'
    

    awk 배열 요소 삭제
  • delete arr[idx]: 배열 arr[idx] 요 소 를 삭제 합 니 다.
  • 존재 하지 않 는 요 소 를 삭제 하면 오류 가 발생 하지 않 습 니 다
  • delete arr: 배열 의 모든 요 소 를 삭제 합 니 다
  • $ awk 'BEGIN{arr[1]=1;arr[2]=2;arr[3]=3;delete arr[2];print length(arr)}'
    2
    

    awk 에서 배열 여 부 를 검사 합 니 다.isarray(arr) 은 arr 가 배열 인지 아 닌 지 를 검사 하 는 데 사용 할 수 있 으 며, 배열 이 라면 1 을 되 돌려 주지 않 으 면 0 을 되 돌려 줍 니 다.typeof(arr) 은 데이터 형식 을 되 돌려 줄 수 있 으 며, arr 가 배열 이 라면 "array"로 되 돌려 줍 니 다.
    awk 'BEGIN{
        arr[1]=1;
        print isarray(arr);
        print (typeof(arr) == "array")
    }'
    

    awk 테스트 요소 가 배열 에 있 는 지 여부
    요소 가 배열 에 있 는 지 아래 의 방식 으로 테스트 하지 마 십시오.
    if(arr["x"] != ""){...}
    

    이것 은 두 가지 문제 가 있다.
  • arr ["x"] 가 존재 하지 않 으 면 이 요 소 를 즉시 만 들 고 빈 문자열
  • 으로 설정 합 니 다.
  • 일부 요소 의 값 자체 가 빈 문자열
  • 입 니 다.
    배열 구성원 테스트 연산 자 in 을 사용 하여 테스트 해 야 합 니 다:
    #   ,idx    index,        
    if (idx in arr){...}
    

    색인 idx 가 배열 에 있 는 지, 존재 하면 1 을 되 돌려 주 고, 존재 하지 않 으 면 0 을 되 돌려 줍 니 다.
    awk '
        BEGIN{
        #         :www.junmajinlong.com
            arr[1]=1;
            arr[2]=2;
            arr[3]=3;
    
            arr[1]="";
            delete arr[2];
    
            print (1 in arr);  # 1
            print (2 in arr);  # 0
        }'
    

    awk 배열 옮 겨 다 니 기
    awk 는 배열 을 옮 겨 다 니 는 변 체 를 제공 합 니 다:
    for(idx in arr){print arr[idx]}
    

    awk 배열 은 관련 배열 이기 때문에 요 소 는 연속 되 지 않 습 니 다. 즉, 순서 가 없다 는 것 입 니 다.awk 배열 을 옮 겨 다 닐 때 순 서 는 예측 할 수 없습니다.
    예 를 들 면:
    #         :www.junmajinlong.com
    awk '
        BEGIN{
            arr["one"] = 1
            arr["two"] = 2
            arr["three"] = 3
            arr["four"] = 4
            arr["five"] = 5
    
            for(i in arr){
                print i " -> " arr[i]
            }
        }
    '
    

    그 밖 에 for(i=0;i , awk 。 , 。 을 함부로 사용 하지 마 세 요.
    예 를 들 면:
    #         :www.junmajinlong.com
    awk '
        BEGIN{
            arr[1] = "one"
            arr[2] = "two"
            arr[3] = "three"
            arr[4] = "four"
            arr[5] = "five"
            arr[10]= "ten"
    
            for(i=0;i<=10;i++){
                if(i in arr){
                    print arr[i]
                }
            }
        }
    '
    

    awk 복잡 한 색인 배열
    awk 에 서 는 단순 한 배열 이 두 개의 정 보 를 저장 할 수 있 는 경우 가 많 습 니 다. 하나의 색인, 하나의 값 입 니 다.그러나 일부 장면 에서 이런 간단 한 저장 능력 은 복잡 한 수 요 를 처리 할 때 곤경 에 빠 질 수 있다.
    더 많은 정 보 를 저장 하기 위해 방식 중 하 나 는 3 부, 4 부 등 정 보 를 모두 특수 한 방식 으로 값 에 저장 하 는 것 이지 만 이런 방식 은 실제 사용 과정 에서 불편 하고 매번 값 을 나 누 어 각 부분의 값 을 꺼 내야 한다.
    또 다른 방식 은 3 부, 4 부 등 정 보 를 색인 에 저장 하고 여러 개의 데 이 터 를 하나의 전체 로 구성 하여 하나의 색인 을 구성 하 는 것 이다.
    gawk 에 서 는 여러 개의 데이터 정 보 를 하나의 색인 으로 조합 하 는 기능 을 제공 합 니 다.기본 방식 은 arr[x,y] 이 고 그 중에서 x 와 y 는 결합 하여 하나의 색인 으로 구축 하 는 두 부분의 데이터 정보 입 니 다.쉼표 는 아래 의 구분자 라 고 하 는데, 색인 을 만 들 때 미리 정 의 된 변수 인 SUBSEP 의 값 에 따라 여러 개의 색인 을 조합 합 니 다.그래서 arr[x,y] 은 사실 arr[x SUBSEP y] 과 완전히 등가 된다.
    예 를 들 어 SUBSEP 가 '@' 으로 설정 되면 arr[5,12] = 512 이 저 장 될 때 실제 색인 은 5@12 이 므 로 이 요 소 를 방문 하려 면 arr["5@12"] 을 사용 해 야 한다.
    SUBSEP 의 기본 값 은 \034 으로 인쇄 할 수 없 는 문자 로 문자열 에 거의 나타 나 지 않 습 니 다.
    만약 우리 가 원한 다 면, 우 리 는 스스로 여러 개의 데 이 터 를 조합 하여 하나의 색인 으로 구축 할 수 있다. 예 를 들 어 arr[x" "y] 이다.그러나 awk 는 이런 더욱 간편 한 방식 을 제공 하여 직접 사용 하면 된다.
    이러한 복잡 한 배열 의 색인 이 배열 에 있 는 지 시험 하기 위해 서 는 다음 과 같은 방식 을 사용 할 수 있 습 니 다.
    arr["a","b"] = 12
    if (("a", "b") in arr){...}
    

    예 를 들 어 시계 방향 으로 다음 데 이 터 를 거꾸로 돌 립 니 다.
    1 2 3 4 5 6
    2 3 4 5 6 1
    3 4 5 6 1 2
    4 5 6 1 2 3
    
      :
    4 3 2 1
    5 4 3 2
    6 5 4 3
    1 6 5 4
    2 1 6 5
    3 2 1 6
    
    {
      nf = NF
      nr = NR
      for(i=1;i<=NF;i++){
        arr[NR,i] = $i
      }
    }
    
    END{
      for(i=1;i<=nf;i++){
        for(j=nr;j>=1;j--){
          if(j%nr == 1){
            printf "%s
    ", arr[j,i] }else { printf "%s ", arr[j,i] } } } }

    awk 하위 그룹
    하위 배열 은 지수 그룹의 요소 이자 배열 입 니 다. 즉, Array of Array 는 하위 배열 (subarray) 이 라 고도 합 니 다.
    awk 도 하위 배열 을 지원 합 니 다. 효과 적 으로 는 내장 배열 이나 다 차원 배열 입 니 다.
    a[1][1] = 11
    a[1][2] = 12
    a[1][3] = 13
    a[2][1] = 21
    a[2][2] = 22
    a[2][3] = 23
    a[2][4][1] = 241
    a[2][4][2] = 242
    a[2][4][1] = 241
    a[2][4][3] = 243
    

    2 차원 배열 을 다음 과 같이 옮 겨 다 닙 니 다.
    for(i in a){
        for (j in a[i]){
            if(isarray(a[i][j])){
                continue
            }
            print a[i][j]
        }
    }
    

    awk 지정 배열 반복 순서
    awk 배열 은 관련 배열 이기 때문에 기본적으로 for(idx in arr) 이 배열 을 옮 겨 다 닐 때 순 서 는 예측 할 수 없습니다.
    그러나 gawk 는 PROCINFO["sorted_in"] 을 제공 하여 옮 겨 다 니 는 요소 순 서 를 지정 합 니 다.두 가지 종류의 값 으로 설정 할 수 있 습 니 다.
  • 사용자 정의 함수
  • 으로 설정
  • 은 다음 awk 에서 미리 정 의 된 값 으로 설정 합 니 다.
  • @unsorted: 기본 값, 옮 겨 다 닐 때 무질서
  • @ind_str_asc: 색인 은 문자열 비교 방식 에 따라
  • 에 걸 쳐 올 라 갑 니 다.
  • @ind_str_desc: 색인 은 문자열 비교 방식 에 따라
  • 을 옮 겨 다 닙 니 다.
  • @ind_num_asc: 색인 은 수치 비교 방식 에 따라 강제로 오름차 순 으로 옮 겨 다 닌 다.따라서 수치 로 변환 할 수 없 는 문자열 색인 은 수치 0 으로
  • 을 비교 합 니 다.
  • @ind_num_desc: 색인 은 수치 비교 방식 에 따라 강제로 내림차 순 으로 옮 겨 다 닌 다.따라서 수치 로 변환 할 수 없 는 문자열 색인 은 수치 0 으로
  • 을 비교 합 니 다.
  • @val_type_asc: 값 상승 순서에 따라 비교 한 결과 수치 유형 이 앞 에 나 타 났 고 그 다음 에 문자열 유형 이 나 타 났 으 며 마지막 으로 배열 류 (즉, num)
  • 이 라 고 생각 합 니 다.
  • @val_type_desc: 값 내림차 순 으로 비교 한 결과 배열 유형 이 앞 에 나 타 났 고 그 다음 에 문자열 유형 이 나 타 났 으 며 마지막 으로 수치 형 (즉, num)
  • 이 라 고 생각 합 니 다.
  • @val_str_asc: 값 상승 순 에 따라 비교 하고 수 치 를 문자열 로 바 꾸 어 비교 하 며 배열 은 끝부분 에 나타난다 (즉, str)
  • 참조).
  • @val_str_desc: 값 의 내림차 순 으로 비교 하고 수 치 를 문자열 로 바 꾸 어 비교 하 며 배열 은 머리 에 나타난다 (즉, str)
  • 참조).
  • @val_num_asc: 값 상승 순서 에 따라 문자열 을 수치 로 바 꾸 어 비교 한 다음 에 배열 은 꼬리 부분 에 나타난다 (즉, num)
  • 참조).
  • @val_num_desc: 값 의 내림차 순 으로 비교 하고 문자열 을 수치 로 바 꾸 어 비교 하 며 배열 은 머리 에 나타난다 (즉, num)
  • 이 라 고 생각 합 니 다).

    예 를 들 면:
    awk '
      BEGIN{
        arr[1] = "one"
        arr[2] = "two"
        arr[3] = "three"
        arr["a"] ="aa"
        arr["b"] ="bb"
        arr[10]= "ten"
    
        #PROCINFO["sorted_in"] = "@ind_num_asc"
        #PROCINFO["sorted_in"] = "@ind_str_asc"
        PROCINFO["sorted_in"] = "@val_str_asc"
        for(idx in arr){
          print idx " -> " arr[idx]
        }
    }'
    
    a -> aa
    b -> bb
    1 -> one
    2 -> two
    3 -> three
    10 -> ten
    
    #         :www.junmajinlong.com
    

    사용자 정의 정렬 함수 로 지정 하면 함수 형식 은 다음 과 같 습 니 다.
    function sort_func(i1,v1,i2,v2){
        ...
        return <0;0;>0
    }
    

    그 중에서 i1 과 i2 는 매번 두 요소 의 색인 이 고 v1 과 v2 는 이 두 색인 의 대응 값 이다.
    반환 값 이 0 보다 작 으 면 i1 이 i2 앞 에 있 고 i1 이 먼저 옮 겨 다 니 는 것 을 의미 합 니 다. 0 과 같 으 면 i1 과 i2 가 같은 값 관 계 를 가지 고 있 음 을 의미 합 니 다. 옮 겨 다 니 는 순 서 는 보장 할 수 없습니다. 0 보다 크 면 i2 가 i1 보다 먼저 옮 겨 다 니 는 것 을 의미 합 니 다.
    예 를 들 어 배열 요 소 를 수치 크기 에 따라 옮 겨 다 니 는 순 서 를 결정 합 니 다.
    awk '
    function cmp_val_num(i1, v1, i2, v2){
      if ((v1 - v2) < 0) {
        return -1
      } else if ((v1 - v2) == 0) {
        return 0
      } else {
        return 1
      }
      # return (v1-v2)
    }
    
    NR > 1 {
      arr[$0] = $4
    }
    
    END {
      PROCINFO["sorted_in"] = "cmp_val_num"
      for (i in arr) {
        print i
      }
    }' a.txt
    

    예 를 들 어 배열 요소 값 의 문자 크기 에 따라 비교 합 니 다.
    function cmp_val_str(i1,v1,i2,v2) {
        v1 = v1 ""
        v2 = v2 ""
        if(v1 < v2){
            return -1
        } else if(v1 == v2){
            return 0
        } else {
            return 1
        }
        # return (v1 < v2) ? -1 : (v1 != v2)
    }
    
    NR>1{
        arr[$0] = $2
    }
    
    END{
        PROCINFO["sorted_in"] = "cmp_val_str"
        for(line in arr)
        {
            print line
        }
    }
    

    예 를 들 어 요소 값 을 수치 에 따라 오름차 순 으로 비교 하고 같은 경우 첫 번 째 필드 ID 에 따라 수치 내림차 순 으로 비교 합 니 다.
    awk '
    function cmp_val_num(i1,v1,i2,v2,    a1,a2) {
        if (v11{
        arr[$0,$1] = $4
    }
    
    END{
        PROCINFO["sorted_in"] = "cmp_val_num"
        for(str in arr){
            split(str, a, SUBSEP)
            print a[1]
        }
    }
    
    ' a.txt
    

    위 에서 사용 한 arr[x,y] 은 추가 정 보 를 저장 하고 아래 는 arr[x][y] 다 차원 배열 의 방식 으로 추가 정 보 를 저장 하여 같은 정렬 기능 을 실현 한다.
    NR>1{
      arr[NR][$0] = $4
    }
    
    END{
      PROCINFO["sorted_in"] = "cmp_val_num"
      for(nr in arr){
        for(line in arr[nr]){
          print line
        }
      #         :www.junmajinlong.com
      }
    }
    
    function cmp_val_num(i1,v1,i2,v2,   ii1,ii2){
      #   v1/v2   , $0  
      for(ii1 in v1){ }
      for(ii2 in v2){ }
    
      if(v1[ii1] < v2[ii2]){
        return -1
      }else if(v1[ii1] > v2[ii2]){
        return 1
      }else{
        return (i2 - i1)
      }
    }
    

    이 밖 에 gawk 는 두 개의 내 장 된 함수 asort () 와 asorti () 를 제공 하여 배열 을 정렬 합 니 다.

    좋은 웹페이지 즐겨찾기