다음과 같은 열이 포함된 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>1
awk
헤더(첫 번째 줄)가 무시된다는 의미입니다 .
마찬가지로 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