在PowerShell中等同于bash sort的命令

3
在Bash中,我有以下内容:
git verify-pack -v .git/objects/pack/pack-*.idx | grep -v chain | sort -k3nr

输出如下:

...
d0a5144e720923b85489e62fe2f9699c8340a90e blob   5 16 106352184 1 ba72dc312a0fc209570b065fd6206c35f87f1198
58f23716aefb940d7d7ea44c1f3004416ac5f065 blob   4 14 12686887 1 89635906c50a2b6e89a78edc6e20e43015dfaa93
81a12bc733bffe5aab087c277f7f289f82975ac0 tree   4 14 110911883 2 10b9544959d69a4cd13f817c883b0b329c59d6d3
8397914fbc571787ff21320903091e4d2ef50907 tree   4 14 110911733 1 c641e2aee4f50a04b539ca40266b0a8718da1570
fe277f883e6cebe9a74d593b7be650ba7610bdfb blob   4 14 55841383 2 180071e183d47e204255be3009ba53a1d4ad069e
5f282702bb03ef11d7184d19c80927b47f919764 blob   3 12 9966998
.git/objects/pack/pack-44f6fe97b177e9c6b978dfe7879b9cf47a98748b.pack: ok
.git/objects/pack/pack-5009b2f54d6bae62e230c593b496d49e45cc5032.pack: ok
.git/objects/pack/pack-69467a1623c6d40146fae8f2e8da9c6ce0bdb5d8.pack: ok
.git/objects/pack/pack-740b36b772adf621529ca11126536f5727c3666d.pack: ok
.git/objects/pack/pack-923e6174d0fb5eca889bd983a7b2305b21c7b0ad.pack: ok
.git/objects/pack/pack-b1777793d03a38f70ad69f81bedfdd4c0cb82348.pack: ok
.git/objects/pack/pack-bf4951ba56f92700e5686fd9f385cb2cb9436b54.pack: ok
.git/objects/pack/pack-f3a758460a0a075a64e84bbb378162969cbcacf2.pack: ok
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 blob   0 9 13814182

基于以下链接的内容: Equivalent of git verify-pack -v | sort | tail 和下面的建议,我正在尝试从PowerShell执行相同的操作:

  git verify-pack -v (Get-ChildItem ".git\objects\pack\pack-*.idx")`
  | Select-String -NotMatch -Pattern "chain" `
  | % { $_.Line } `
  | Sort {[int]($_ -split ' ')[3]}

结果的最后一部分是这样的:
    ...
    f583c1c4736334f88a379f35ba74966cb61eea32 commit 1026 392 652028
    9a92d4985f549b587410145b0c59953f2e58d0a1 commit 641 408 870110
    e061e2ddfea5fe4c400a5277ff084ab05603a366 commit 1436 411 533973
    15160a6ca1c7137fc8b52676291d2e5429428949 commit 1351 414 877215
    bac4a21a5a4c7da14276415c2e8de999d20609e6 commit 1587 420 908493
    a2af58831c77adb0904cb99561ddf80b73994b38 commit 845 420 444487
    ced62e9fe611f449510d5c0a637d7a673f9b20b9 commit 774 427 480249
    22ccd25bb0e6de82373d0b95f3131d3592cedecf commit 1821 438 907649
    534017b3e8707f1524a3ac1f13934729245d54dd commit 1303 443 36133
    a46ea0dd61280c65d3ef3d69559341eb9029358b commit 1161 451 973617
    8328ecd726d18a46ea72da04c19af987e6715944 commit 1424 459 398884
    45bd595436e20a98221847040194ae5ab5660a8e commit 1835 463 758557
    319455259cad21e73e17890f4e9cba9c06e845bf commit 1343 472 449402
    177de1b8f8320877b029d82e49b9dbc3b507fb37 commit 1983 483 468022
    e266ad16939806066d3f4c7baca0afc88d67bfe6 commit 1455 497 309591
    45d338ef45f320289c03cd96e5f1fb3ec505b6d9 commit 1645 517 583296
    eb4c15e3a1e582f9a5c20073a9c24dd79825abf1 commit 2137 530 57469
    3043a3041960397925480dd6a5f30b9498adeed9 commit 6153 718 1011624
    f5ea0c33d06eac001f7d3b2830b1ccd841a92247 commit 7255 1130 137037

这与bash的输出不同。

我已经验证了到这一步为止,bash和powershell命令的输出是相同的:

# Bash
git verify-pack -v .git/objects/pack/pack-*.idx | grep -v chain

#PowerShell
git verify-pack -v (Get-ChildItem ".git\objects\pack\.git\objects\pack\pack-*.idx") | Select-String -NotMatch -Pattern "chain"

任何建议为什么在PowerShell中调用sort更改输出结果?
我使用以下文件test.small.input进行了最小测试:
b97916c219f1f0d229dc93eadb8e1bee8e021a66 blob   24 33 132341747 1 f8b3ab8251d3e013d194c3d999d0725be96c899e
c62cc937c9a30f04900b50feb7d9b3ac350ed4f3 blob   31 38 132341780 1 f8b3ab8251d3e013d194c3d999d0725be96c899e
e3034004302aeb24899dc93460379244cca9009f tree   262 215 132341818
ab4c1f12673e2556dce2266846a8f0533aa2ab7e tree   443 304 132342033
31e2c7a673f5e05c0c9b3d48e07eee0c2e205edb tree   55 70 132342337 1 ab4c1f12673e2556dce2266846a8f0533aa2ab7e

使用bash进行排序:

sort C:/tmp/test.small.input -k3nr

或者

sort C:/tmp/test.small.input -k4nr

提供:

ab4c1f12673e2556dce2266846a8f0533aa2ab7e tree   443 304 132342033
e3034004302aeb24899dc93460379244cca9009f tree   262 215 132341818
31e2c7a673f5e05c0c9b3d48e07eee0c2e205edb tree   55 70 132342337 1 ab4c1f12673e2556dce2266846a8f0533aa2ab7e
c62cc937c9a30f04900b50feb7d9b3ac350ed4f3 blob   31 38 132341780 1 f8b3ab8251d3e013d194c3d999d0725be96c899e
b97916c219f1f0d229dc93eadb8e1bee8e021a66 blob   24 33 132341747 1 f8b3ab8251d3e013d194c3d999d0725be96c899e

使用PowerShell对同一文件进行排序:

  Get-Content c:\tmp\test.small.input | Sort {[int]($_ -split ' ')[4]} -Descending

提供:

ab4c1f12673e2556dce2266846a8f0533aa2ab7e tree   443 304 132342033
e3034004302aeb24899dc93460379244cca9009f tree   262 215 132341818
31e2c7a673f5e05c0c9b3d48e07eee0c2e205edb tree   55 70 132342337 1 ab4c1f12673e2556dce2266846a8f0533aa2ab7e
c62cc937c9a30f04900b50feb7d9b3ac350ed4f3 blob   31 38 132341780 1 f8b3ab8251d3e013d194c3d999d0725be96c899e
b97916c219f1f0d229dc93eadb8e1bee8e021a66 blob   24 33 132341747 1 f8b3ab8251d3e013d194c3d999d0725be96c899e

看起来PowerShell/Split/index和bash index的工作方式存在一些差异。


sort {[int]($_-split' ')[2]} -Descending 是什么意思? - user4003407
这会得到另一个结果,但不同于bash输出的结果。 - u123
1个回答

2
我在我的git库中的pack目录中没有任何内容,因此我无法进行测试,但我怀疑原因是Select-String返回的不是[string]类型,而是匹配对象。
在PowerShell中比较命令输出和其他内容时必须小心。它们看起来可能相同,但实际上并不相同。通常情况下,PowerShell会返回某种对象,并且某些对象可以控制其显示方式。有时,输出被特定格式化以类似于bash或命令提示符命令的形式呈现。
要检查,请使用Get-Member.GetType()方法。
git verify-pack -v (Get-ChildItem ".git\objects\pack\.git\objects\pack\pack-*.idx") | 
    Select-String -NotMatch -Pattern "chain" | Get-Member

请注意,在使用此实现时要小心;由于管道的工作方式,数组将被展开,而Get-Member将为数组中的每个对象提供信息(仅限唯一的,如果有100个字符串,它只会显示一次信息)。这可能是您想要的,或者您可能想了解集合类型。
在这种情况下,您可以这样使用:
Get-Member -InputObject (git verify-pack -v (Get-ChildItem ".git\objects\pack\.git\objects\pack\pack-*.idx") | 
    Select-String -NotMatch -Pattern "chain")

# or

$returnValue = git verify-pack -v (Get-ChildItem ".git\objects\pack\.git\objects\pack\pack-*.idx") | Select-String -NotMatch -Pattern "chain"
Get-Member -InputObject $returnValue

如果您确认没有获取到字符串,可以尝试使用正确的解决方案(可能是使用Select-Object -ExpandPropertyForEach-Object)。

Select-String 确实返回自定义对象(不仅是匹配项,还包括其周围的上下文等)。您可以通过使用 Select-String ... | % Line 来获取字符串。或者只需使用 Get-Content 并使用 -match 进行过滤。 - Joey
我刚刚尝试按照你的建议添加了% Line,但没有任何效果。无论我使用它与否,输出结果都是相同的。 - u123
@u123 我认为Joey的代码有点问题,正确的应该是 Select-String | % { $_.Line },你也可以使用 Select-String | Select-Object -ExpandProperty Line 来实现相同的功能。 - briantist
我根据您的更正进行了更新,现在我得到了另一种结果,但仍然与Bash的结果不同。 - u123
@briantist:在最近的PowerShell版本中,您只需将属性名称传递给ForEach-Object,然后它将被展开。(这里是PowerShell v5) - Joey
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接