排序命令 - 按月不起作用?

排序命令 - 按月不起作用?

我有一个时间戳数组...

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

要仅对给定列应用“反向”,请指定它-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

一些perl:

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 所提到的-r,月份的键中似乎需要-k2,2Mr,因为M在 keydef 中指定修饰符会重置r该 keydef 的修饰符。因此,要按降序对时间戳进行排序,您需要指定-r“全局”以及Mr“月份”keydef。

在考虑了所有有用的答案并做了更多测试之后,我发现在我的情况下没有必要指定数字排序,并且仅按年份-k3,3和月份排序确实足够了-k2,2Mr

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

相关内容