awk는 파일에서 필요한 데이터를 가져와 열별로 인쇄합니다.

awk는 파일에서 필요한 데이터를 가져와 열별로 인쇄합니다.

아래와 같은 텍스트 파일이 있습니다.

mark     10 20 30
lawrence 40 22 60
mark     11 12 13
mike     15 16 17
lawrence 21 22 23
mike     31 32 33
mike     41 42 47

이를 처리하고 다음 조건을 충족하는 출력을 생성하고 싶습니다.

  • 고유 이름당 하나의 행(첫 번째 열) 따라서 위의 예에서는 "Mark", "Lawrence" 및 "Mike"에 대해 각각 하나씩 세 개의 출력 라인이 있어야 합니다.
  • 출력은 입력과 표면적으로 유사해 보입니다.
    • 4개의 열.
    • 출력의 첫 번째 열은 이름(입력의 첫 번째 열)입니다.
    • 두 번째, 세 번째, 네 번째 열은 정수입니다.
  • 두 번째 열은 이름이 첫 번째 열에 나타나는 횟수입니다.
  • 세 번째 열은 첫 번째 열에 이름이 나타나는 횟수이고, 세 번째 열에 입력한 값은 20입니다.
  • 네 번째 열은 첫 번째 열에 이름이 나타나는 횟수이고, 세 번째 열에 입력한 값은 22입니다.

예상 출력:

mark     2  1  0
mike     3  0  0
lawrence 2  0  2

나는 썼다

... | awk '{ c[$1]++ } END { for (name in c) print name, c[name] }'

내 코드는 출력만 합니다.

mark     2 
mike     3 
lawrence 2 

답변1

awk '
    {name[$1]++}      #Counts how many times each name appear
    $3==20{x20[$1]++} #Counts how many times 20 appears in third column
    $3==22{x22[$1]++} #Counts how many times 22 appears in third column
    END{
        for (i in name){
            printf "%s %d %d %d\n",i,name[i],x20[i],x22[i]
        }
    }
' file

산출:

mike 3 0 0
lawrence 2 0 2
mark 2 1 0

답변2

비슷한 개념@quasimodo의 답변그러나 한 곳에서는 3 대신 값 20과 값이 사용되며 22값은 배열 이름에 하드코딩되지 않습니다.

awk '
    { namesCnt[$1]++; pairsCnt[$1,$3]++ }
    END {
        for (name in namesCnt) {
            print name, namesCnt[name], pairsCnt[name,20]+0, pairsCnt[name,22]+0
        }
    }
' file

답변3

질문에서와 같이 출력을 열로 정렬하려면 다른 답변 중 하나를 선택하십시오(콰지모도의또는 에드 모튼의)로 파이프하여 column -t.

관련 정보