배열 사용awk

배열 사용awk

다음과 같은 열이 포함된 CSV가 있습니다.

Team    Other Data  More Data   Result  Time
Knicks      A          F         Loss    2p
Celtics     B          E         Win     2p
Lakers      C          D         Loss    3p
Lakers      D          C         Loss    4p
Knicks      E          B         Win     4p
Lakers      F          A         Win     5p

CSV를 읽고 각 팀의 승패를 출력하는 방법은 무엇입니까?

예를 들어, 내가 원하는 출력은 다음과 같습니다.

1 Loss Knicks
1 Win Knicks
1 Win Celtics
2 Loss Lakers
1 Win Lakers

이제 다음 코드가 있습니다.

#!/bin/bash
while IFS=, read -r team result
do
  echo $team, $result
done < teams.csv

다음과 같은 출력이 생성됩니다.

Team, Result   
Knicks, Loss
Celtics, Win
Lakers, Loss
Lakers, Loss
Knicks, Win

각 팀의 각 결과 발생 횟수를 어떻게 계산하고 저장할 수 있나요? 이상적으로는 이 데이터를 팀별로 정렬하고 싶습니다.

답변1

배열 사용awk

입력 파일의 필드가 하나 이상의 공백 문자로 구분된 경우 필드 구분 기호를 선언할 필요가 없습니다.

awk 'NR>1 && NF { league[$1][$4]++ } END { for ( team in league ) for ( results in league[team] ) print league[team][results],results,team }' teams.txt

화면에 맞게 형식이 지정된 동일한 코드:

awk 'NR>1 && NF { league[$1][$4]++ }
     END { for ( team in league )
           for ( results in league[team] )
           print league[team][results],results,team }' teams.txt

여기서는 리그(입력 파일)에서 각 팀( , 첫 번째 게임)의 승패( , 네 번째 게임) 횟수를 계산합니다 league[$1][$4]++.$4$1

NR>1awk헤더(첫 번째 줄)가 무시된다는 의미입니다 .

마찬가지로 NF(의 약어 )는 하나 이상의 필드가 포함된 행만 검사한다는 NF>0의미입니다 . awk즉, NF빈 줄을 건너뜁니다.

NR>1 && NF섹션에서는 입력 파일을 검사하고 배열을 만듭니다. 완료되면 이 END섹션에서는 배열을 인쇄합니다.

입력 파일의 필드가 쉼표로 구분된 경우 BEGIN { FS="," ; OFS=" " }설정 입력( FS) 및 출력( OFS) 필드 구분 기호를 추가합니다.

awk 'BEGIN { FS="," ; OFS=" " } NR>1 && NF { league[$1][$4]++ } END { for ( team in league ) for ( results in league[team] ) print league[team][results],results,team }' teams.csv

화면에 맞게 형식이 지정된 동일한 코드:

awk 'BEGIN { FS="," ; OFS=" " }
         NR>1 && NF { league[$1][$4]++ }
         END { for ( team in league )
               for ( results in league[team] )
               print league[team][results],results,team }' teams.csv

산출:

1 Win Knicks
1 Loss Knicks
1 Win Lakers
2 Loss Lakers
1 Win Celtics

| sort -t " " -k 3 -k 2,2해당 코드 끝에 추가하고 팀별로 정렬한 다음 각 팀의 결과별로 정렬합니다.

정렬된 출력:

1 Win Celtics
1 Loss Knicks
1 Win Knicks
2 Loss Lakers
1 Win Lakers

답변2

당신이 해야 할 일은 파일을 정렬하고 이를 전달하여 uniq -c고유한 발생 횟수를 계산하는 것뿐입니다.

sort teams.csv | uniq -c

그러면 다음과 같은 출력이 생성됩니다.

      1 Celtics,Win
      1 Knicks,Loss
      1 Knicks,Win
      2 Lakers,Loss

답변3

GNU datamash를 사용하십시오(중요하다면 awk를 사용하여 열을 재정렬하세요):

$ datamash -W --header-in groupby 1,4 count 4 < teams.csv | awk '{print $3, $2, $1}'
1 Loss Knicks
1 Win Celtics
2 Loss Lakers
1 Win Knicks
1 Win Lakers

우리가 있기 때문에 참고하시기 바랍니다아니요datamash에 정렬을 요청하면 이미 인접한 결과만 그룹화됩니다.

귀하의 데이터가 실제로반점분리 및 교체 -W 통과 -t,

답변4

그냥 사용 sort하고 파이프로 연결할 수도 있지만 uniq -c여기에는 Team, Result.

이를 방지하려면:

$ awk 'NR>1 {print $4,$1}' team.csv | sort -k2 | uniq -c

각 부분을 설명하세요.

  • awk 'NR>1 {print $4,$1}'- 첫 번째 행보다 큰 모든 행과 결과를 인쇄하고 그 뒤에 열 4와 1에 지정된 팀과 결과를 인쇄합니다.
  • sort -k2- 팀별로 정렬하면 awk작업 후 두 번째 열이 됩니다.
  • uniq -c- 고유한 발생 횟수 계산

팀별로 정렬된 출력:

1 Win Celtics
1 Loss Knicks
1 Win Knicks
2 Loss Lakers
1 Win Lakers

관련 정보