정렬 명령 - 월별 정렬이 작동하지 않나요?

정렬 명령 - 월별 정렬이 작동하지 않나요?

타임스탬프 배열이 있습니다.

arr[0]="04-Feb-2021-21-05-48"
arr[1]="18-Jan-2021-12-19-48"
arr[2]="25-Jan-2021-00-24-29"
arr[3]="26-Jan-2021-00-28-33"
arr[4]="04-Feb-2021-21-06-49"
arr[5]="18-Jan-2021-12-19-48"
arr[6]="25-Jan-2021-00-24-29"
arr[7]="26-Jan-2021-00-28-33"

이 배열을 정렬하고 다음 명령을 사용하여 타임스탬프를 새 배열로 정렬하고 싶습니다.

IFS=$'\n' sorted=($(sort -r -t- -k2.1,2.3M <<<"${arr[*]}")); unset IFS
printf "[%s]\n" "${sorted[@]}"

이 출력을 얻었지만 원하는 결과가 아닙니다.

[26-Jan-2021-00-28-33]
[26-Jan-2021-00-28-33]
[25-Jan-2021-00-24-29]
[25-Jan-2021-00-24-29]
[18-Jan-2021-12-19-48]
[18-Jan-2021-12-19-48]
[04-Feb-2021-21-06-49]
[04-Feb-2021-21-05-48]

대신 타임스탬프를 내림차순으로 정렬하고 싶습니다.
그러면 이 결과를 어떻게 얻을 수 있나요?

[04-Feb-2021-21-06-49]
[04-Feb-2021-21-05-48]
[26-Jan-2021-00-28-33]
[26-Jan-2021-00-28-33]
[25-Jan-2021-00-24-29]
[25-Jan-2021-00-24-29]
[18-Jan-2021-12-19-48]
[18-Jan-2021-12-19-48]

이 버전의 정렬 명령을 시도했지만 그 중 아무 것도 작동하지 않았습니다 ...

IFS=$'\n' sorted=($(sort -r -t- -k3.1,3.4 -k2.1,2.3M <<<"${arr[*]}")); unset IFS
IFS=$'\n' sorted=($(sort -r -t- -k2.1,2.3M <<<"${arr[*]}")); unset IFS
IFS=$'\n' sorted=($(sort -t- -k2.1,2.3M <<<"${arr[*]}")); unset IFS

고쳐 쓰다

월 필드를 기준으로 타임스탬프 배열을 정렬하는 것이 아니라 타임스탬프를 내림차순으로 정렬하고 싶다는 점을 명확히 하기 위해 질문을 업데이트했습니다.

건배.

답변1

주어진 열에만 "reverse"를 적용하려면 지정하십시오.뒤쪽에이것 -k:

sort -t- -k2.1,2.3Mr
#                  ~

답변2

-r반전하려는 키에 반전을 사용하되, 원하는 출력을 얻으려면 이 방법을 사용해 보세요. 복잡한 sort' 를 사용하는 대신 문자열을 적절한 날짜 형식으로 변환한 다음 정렬한 다음 다시 원래 형식으로 돌아가서 복잡하게 만들어 보겠습니다.

printf "%s\n" "${sorted[@]}" | \
  awk -F'-' '{ print $1" " tolower($2)" "$3" "$4":"$5":"$6 }' | \ # 04 feb 2021 21:05:48
  xargs -I {} date -d {} +"%Y-%m-%d %H:%M:%S" | \ # 2021-02-04 21:05:48
  sort -k1r | \
  xargs -I {} date -d {} +"[%d-%b-%Y-%H-%M-%S]"

산출:

[04-Feb-2021-21-06-49]
[04-Feb-2021-21-05-48]
[26-Jan-2021-00-28-33]
[26-Jan-2021-00-28-33]
[25-Jan-2021-00-24-29]
[25-Jan-2021-00-24-29]
[18-Jan-2021-12-19-48]
[18-Jan-2021-12-19-48]

답변3

일부 펄:

printf '%s\n' "${arr[@]}" \
| perl -MTime::Piece -lne '
    $t = Time::Piece->strptime($_, "%d-%b-%Y-%H-%M-%S");
    push @dates, [$t, $_];
    END {print for map {$_->[1]} sort {$b->[0] <=> $a->[0]} @dates}
  '

답변4

@ilkkachu가 지적했듯이 기본적으로 각 키의 시작 및 중지 위치는 첫 번째 및 끝 위치이므로 내 경우에는 -k3,3r대신 생략할 수 있습니다 -k3.1,3.4r.

@choroba의 솔루션 sort -t- -k2.1,2.3Mr은 내 문제를 해결하는 데 가장 도움이 되었습니다. 실제로 "월" 필드를 기준으로 정렬할 때 키에 -r을 포함시켜야 할 것 같습니다... 그래서 sort -t- -k2,2Mr는 아니지만sort -r -t- -k2,2M

@altblue 에 의해 생성된 월 필드뿐만 아니라 타임스탬프를 내림차순으로 정렬해야 한다는 점을 명확히 한 후, 전반적으로 가장 좋은 대답은 다음과 같습니다.

sort -t- -k3,3nr -k2,2Mr -n -r

-r하지만 올해의 키에는 필요하지 않다고 생각합니다 -k3,3nr. @Toby Speight가 언급했듯이 keydef에 수정자를 지정하면 해당 keydef에 대한 수정자가 재설정 되므로 -r월 키가 필요한 것 같습니다 . 따라서 타임스탬프를 내림차순으로 정렬하려면 "전역" 키 정의와 "월" 키 정의를 지정해야 합니다.-k2,2MrMr-rMr

유용한 답변을 모두 고려하고 추가 테스트를 수행한 후 제 경우에는 숫자 순서를 지정할 필요가 없으며 -k3,3연도 및 월별로 정렬하는 것만으로도 충분하다는 것을 알았습니다 -k2,2Mr.

sort -r -t- -k3,3 -k2,2Mr

관련 정보