요일별로 정렬하는 방법은 무엇입니까?

요일별로 정렬하는 방법은 무엇입니까?

두 개의 파일이 있습니다.

파일 1:

Dave 734.838.9800  
Bob 313.123.4567  
Carol 248.344.5576  
Mary 313.449.1390  
Ted 248.496.2204  
Alice 616.556.4458   

파일 2:

Bob Tuesday  
Carol Monday  
Ted Sunday   
Alice Wednesday  
Dave Thursday    
Mary Saturday  

두 개의 파일을 병합했습니다.

file3은 다음과 같아야 합니다.

Name      On-Call     Phone  
Carol     MONDAY      248.344.5576  
Bob       TUESDAY     313.123.4567  
Alice     WEDNESDAY   616.556.4458  
Dave      THURSDAY    734.838.9800  
Nobody    FRIDAY      634.296.3356  
Mary      SATURDAY    313.449.1390  
Ted       SUNDAY      248.496.2204  

하지만 나는 하루 일과를 체계적으로 정리할 수 없습니다. 어떻게 해야 하나요?

답변1

다른 방법은 다음과 같습니다(짧은 버전, 임시 파일 없음).

{ printf %s\\n "Name On-Call Phone"; 
join -a1 -j2 -o 1.1 2.1 1.2 2.3 -e "Nobody" \
<(printf %s\\n '5 Friday' '1 Monday' '6 Saturday' '7 Sunday' '4 Thursday' '2 Tuesday' '3 Wednesday') \
<(join <(sort file2) <(sort file1) | sort -k2) | sort -k2n | sort -k1n | \
cut -d' ' -f 2-; } | column -t

대문자 날짜 이름이 꼭 필요한 경우 다음을 수행하십시오.

{ printf %s\\n "Name On-Call Phone";  join -a1 -j2 -o 1.1 2.1 1.3 2.3 -e "Nobody" <(cat <<IN
5 Friday FRIDAY
1 Monday MONDAY
6 Saturday SATURDAY
7 Sunday SUNDAY
4 Thursday THURSDAY
2 Tuesday TUESDAY
3 Wednesday WEDNESDAY
IN
) <(join <(sort file2) <(sort file1) | sort -k2) | sort -k2n | sort -k1n | cut -d' ' -f 2-; } | column -t

긴 버전:
두 개의 파일이 있다고 가정해 보겠습니다 file1.

Dave 734.838.9800
Bob 313.123.4567
Carol 248.344.5576
Mary 313.449.1390
Ted 248.496.2204
Alice 616.556.4458
Jimmy 324.555.8867
Harry 422.858.2354
Lou 788.907.6859

그리고 file2:

Bob Tuesday
Carol Monday
Jimmy Wednesday
Ted Sunday
Alice Wednesday
Dave Thursday
Harry Monday
Mary Saturday
Lou Sunday

우리가 만든 것은 다음과 같습니다 file3.

1 Monday MONDAY
2 Tuesday TUESDAY
3 Wednesday WEDNESDAY
4 Thursday THURSDAY
5 Friday FRIDAY
6 Saturday SATURDAY
7 Sunday SUNDAY

그런 다음 다음을 실행하십시오.

{ printf %s\\n "Name On-Call Phone"; \
join <(sort file2) <(sort file1) | sort -k2 | \
join -a1 -j2 -o 1.1 2.1 1.3 2.3 -e "Nobody" <(sort -k2 file3) - \
| sort -k1n | cut -d' ' -f 2-; } | column -t

또는 한 줄:

{ printf %s\\n "Name On-Call Phone"; join <(sort file2) <(sort file1) | sort -k2 | join -a1 -j2 -o 1.1 2.1 1.3 2.3 -e "Nobody" <(sort -k2 file3) - | sort -k1n | cut -d' ' -f 2-; } | column -t

산출:

Name    On-Call    Phone
Carol   MONDAY     248.344.5576
Harry   MONDAY     422.858.2354
Bob     TUESDAY    313.123.4567
Alice   WEDNESDAY  616.556.4458
Jimmy   WEDNESDAY  324.555.8867
Dave    THURSDAY   734.838.9800
Nobody  FRIDAY     Nobody
Mary    SATURDAY   313.449.1390
Lou     SUNDAY     788.907.6859
Ted     SUNDAY     248.496.2204

작동 방식:
join <(sort file2) <(sort file1) | sort -k2- 처음 두 파일은 두 번째 필드를 기준으로 연결된 다음 출력은 두 번째 열을 기준으로 정렬됩니다.

Carol Monday 248.344.5576
Harry Monday 422.858.2354
Mary Saturday 313.449.1390
Ted Sunday 248.496.2204
Lou Sunday 788.907.6859
Dave Thursday 734.838.9800
Bob Tuesday 313.123.4567
Jimmy Wednesday 324.555.8867
Alice Wednesday 616.556.4458

이는 두 번째 필드를 기반으로 하는 조인 join -a1 -j2 -o 1.1 2.1 1.3 2.3 -e "Nobody" <(sort -k2 file3) -으로 파이프됩니다. file3의 일치하지 않는 줄이 출력에 추가되고 누락된 출력 필드는 다음으로 대체됩니다 .file3-a1-e "Nobody""Nobody"

5 Nobody FRIDAY Nobody
1 Carol MONDAY 248.344.5576
1 Harry MONDAY 422.858.2354
6 Mary SATURDAY 313.449.1390
7 Ted SUNDAY 248.496.2204
7 Lou SUNDAY 788.907.6859
4 Dave THURSDAY 734.838.9800
2 Bob TUESDAY 313.123.4567
3 Jimmy WEDNESDAY 324.555.8867
3 Alice WEDNESDAY 616.556.4458

결과는 다시 파이프되어 sort -k1n | cut -d' ' -f 2-첫 번째 필드의 출력을 숫자로 정렬한 다음 첫 번째 필드를 제거합니다.

Carol MONDAY 248.344.5576
Harry MONDAY 422.858.2354
Bob TUESDAY 313.123.4567
Alice WEDNESDAY 616.556.4458
Jimmy WEDNESDAY 324.555.8867
Dave THURSDAY 734.838.9800
Nobody FRIDAY Nobody
Mary SATURDAY 313.449.1390
Lou SUNDAY 788.907.6859
Ted SUNDAY 248.496.2204

{...}인쇄 헤더와 함께 그룹화 되므로 printf %s\\n "Name On-Call Phone"전체 출력이 파이프로 연결되어 column -t아름답게 표시됩니다.


sortfile3이 이미 두 번째 열에 정렬되어 있는 경우 하나를 건너뛸 수 있습니다(예를 들어 이번에는 간단한 2열 file3 사용).

5 Friday
1 Monday
6 Saturday
7 Sunday
4 Thursday
2 Tuesday
3 Wednesday

"Nobody"예를 들어 다음과 같이 전화번호를 할당합니다 sed 's/Nobody/888.000.8888/2'.

{ printf %s\\n "Name On-Call Phone"; join <(sort file2) <(sort file1) | \
sort -k2 | join -a1 -j2 -o 1.1 2.1 1.2 2.3 -e "Nobody" file3 - | sort -k1n | \
cut -d' ' -f 2-; } | sed 's/Nobody/888.000.8888/2' | column -t

산출:

Name    On-Call    Phone
Carol   Monday     248.344.5576
Harry   Monday     422.858.2354
Bob     Tuesday    313.123.4567
Alice   Wednesday  616.556.4458
Jimmy   Wednesday  324.555.8867
Dave    Thursday   734.838.9800
Nobody  Friday     888.000.8888
Mary    Saturday   313.449.1390
Lou     Sunday     788.907.6859
Ted     Sunday     248.496.2204

답변2

awk '
    BEGIN {
        print "Name On-Call Phone"
        split("MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY SUNDAY", days);
    }
    NR == FNR { day[$1] = $2; next }
    { lines[toupper(day[$1])] = $1 OFS toupper(day[$1]) OFS $2 }
    END {
        for (i=1; i<=7; i++) {
            if (lines[days[i]]) 
                print lines[days[i]]
            else
                print "Nobody", days[i]
        }
    }
' file2 file1 | column -t
Name    On-Call    Phone
Carol   MONDAY     248.344.5576
Bob     TUESDAY    313.123.4567
Alice   WEDNESDAY  616.556.4458
Dave    THURSDAY   734.838.9800
Nobody  FRIDAY
Mary    SATURDAY   313.449.1390
Ted     SUNDAY     248.496.2204

관련 정보