【问题标题】:Sort an PowerShell array according to a part of content in each element根据每个元素中的部分内容对 PowerShell 数组进行排序
【发布时间】:2015-08-26 12:06:46
【问题描述】:

我正在使用一个 powershell 脚本,其中我有一个包含以下数据的数组。下面的每一行都是数组中的一个元素。

每个元素都有两部分,由“/”分隔,一个数字(可以是 1-12 位数字)和一个日期时间。

我需要根据每个元素中给出的日期和时间对数组进行排序。

201410212339/21-Oct-2014 23:50 -
2251/27-Sep-2014 23:02 -
0436/22-Oct-2014 04:47 -
091342/09-Oct-2014 13:53 -
2220743/22-Oct-2014 07:53 -
20140/22-Sep-2014 07:41 -
2190446/19-Oct-2014 04:56 -
2014258/21-Aug-2014 23:21 -
22110/22-Oct-2014 14:21 -
1410221721/22-Jun-2014 17:33 -
130/23-Jul-2014 11:42 -
10231426/23-Feb-2014 14:38 -
231731/23-Jan-2014 17:43 -
0232039/23-Mar-2014 20:51 -

谁能帮我解决这个问题?我想对数组进行排序以访问最新或第二个最新条目并使用与之关联的数字。我可以尝试将每个元素拆分为数字和日期时间并对它们进行排序,但我正在寻找一种更简单的方法。

提前致谢。

【问题讨论】:

  • 其中一些数字以 0 开头。您希望将它们排序为字符串、包含 0 还是数字?
  • @TheMadTechnician:我确实想对数字进行排序,它们将被视为字符串,但元素的排序应使用日期时间完成。

标签: arrays sorting powershell powershell-2.0 powershell-3.0


【解决方案1】:

您可以从每个字符串创建属性,按其排序,然后重新展开原始字符串...类似于:

@"
201410212339/21-Oct-2014 23:50 -
2251/27-Sep-2014 23:02 -
0436/22-Oct-2014 04:47 -
091342/09-Oct-2014 13:53 -
2220743/22-Oct-2014 07:53 -
20140/22-Sep-2014 07:41 -
2190446/19-Oct-2014 04:56 -
2014258/21-Aug-2014 23:21 -
22110/22-Oct-2014 14:21 -
1410221721/22-Jun-2014 17:33 -
130/23-Jul-2014 11:42 -
10231426/23-Feb-2014 14:38 -
231731/23-Jan-2014 17:43 -
0232039/23-Mar-2014 20:51 -
"@ -split "`r`n"|Select @{l='SortMe';e={[int64]$_.split('/')[0]}},@{l='Value';e={$_}}|sort SortMe|Select -Expand Value

这将输出:

130/23-Jul-2014 11:42 -
0436/22-Oct-2014 04:47 -
2251/27-Sep-2014 23:02 -
20140/22-Sep-2014 07:41 -
22110/22-Oct-2014 14:21 -
091342/09-Oct-2014 13:53 -
231731/23-Jan-2014 17:43 -
0232039/23-Mar-2014 20:51 -
2014258/21-Aug-2014 23:21 -
2190446/19-Oct-2014 04:56 -
2220743/22-Oct-2014 07:53 -
10231426/23-Feb-2014 14:38 -
1410221721/22-Jun-2014 17:33 -
201410212339/21-Oct-2014 23:50 -

如果您不希望它们按数字排序并且希望数字按字符串排序,请从中删除 [int64]

【讨论】:

  • 感谢您的回复。我实际上是在尝试根据每个条目中的日期时间部分进行排序,而不是使用每个条目中的数字。
【解决方案2】:

如果您想按日期和时间排序,这是一种方法。

这是你的数组数据

$data = @("201410212339/21-Oct-2014 23:50 -",
"2251/27-Sep-2014 23:02 -",
"0436/22-Oct-2014 04:47 -",
"091342/09-Oct-2014 13:53 -",
"2220743/22-Oct-2014 07:53 -",
"20140/22-Sep-2014 07:41 -",
"2190446/19-Oct-2014 04:56 -",
"2014258/21-Aug-2014 23:21 -",
"22110/22-Oct-2014 14:21 -",
"1410221721/22-Jun-2014 17:33 -",
"130/23-Jul-2014 11:42 -",
"10231426/23-Feb-2014 14:38 -",
"231731/23-Jan-2014 17:43 -",
"0232039/23-Mar-2014 20:51 -")

去除每行末尾多余的字符

$data.replace(" -","")

在每一行前面加上 ticks

中日期的 [datetime] 表示
$data.replace(" -","") | % { [string]([datetime]::Parse($_.split("/")[1]).ticks) + "@" + $_}

排序

$data.replace(" -","") | % { [string]([datetime]::Parse($_.split("/")[1]).ticks) + "@" + $_} | sort-object

如果需要,可以删除前面的日期字符串并在最后恢复垃圾。

$data.replace(" -","") | % { [string]([datetime]::Parse($_.split("/")[1]).ticks) + "@" + $_} | sort-object | %{$_.split("@")[1] + " -"}

结果如下:

231731/23-Jan-2014 17:43 -
10231426/23-Feb-2014 14:38 -
0232039/23-Mar-2014 20:51 -
1410221721/22-Jun-2014 17:33 -
130/23-Jul-2014 11:42 -
2014258/21-Aug-2014 23:21 -
20140/22-Sep-2014 07:41 -
2251/27-Sep-2014 23:02 -
091342/09-Oct-2014 13:53 -
2190446/19-Oct-2014 04:56 -
201410212339/21-Oct-2014 23:50 -
0436/22-Oct-2014 04:47 -
2220743/22-Oct-2014 07:53 -
22110/22-Oct-2014 14:21 -

编辑:

我最初按 [datetime] 排序的尝试没有正常工作

[string]([datetime]::Parse($_.split("/")[1]))

这不适合排序,因为它不按年份或时间排序。 用 ticks 表示 [datetime] 可以解决问题。

[string]([datetime]::Parse($_.split("/")[1]).ticks)

我已经编辑了上面的代码以反映这一点。

【讨论】:

  • 我不知道它是如何工作的,但 $data | sort-object 确实为我工作。不过,我可以从您的回答中学到一些有用的东西。我在使用您的建议时发现了一个错误。如果有不同的年份,则排序时不考虑年份。只考虑日期和月份。
  • @user3543477 感谢您发现该错误。问题是它在转换为字符串的普通日期时间上进行排序。如果你用刻度表示日期时间,问题就会消失。答案已编辑。此外,$data | sort-object 不应该工作,因为它按整个字符串排序。反正对我来说……
【解决方案3】:

您可以将代码块传递给sort 以创建自定义排序属性,而无需重新构建数组。 (捏住 Jan Chrbolka 的日期时间解析):

$getDate = { [datetime]::Parse($_.split("/")[1].replace(' -','')) }
$data | sort $getDate

或对-Descending 进行排序以将其反转。

但是如果不拆分线路,您将无法使用日期和数字,寻找“更简单的方式”似乎有点徒劳。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-24
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    • 2013-04-30
    相关资源
    最近更新 更多