【问题标题】:Equivalent to bash sort in PowerShell等效于 PowerShell 中的 bash 排序
【发布时间】:2016-06-06 13:11:41
【问题描述】:

在 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"

对于 sort 调用为何会更改 PowerShell 中的输出有何建议?

我使用以下文件 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 索引的工作方式存在一些差异。

【问题讨论】:

  • sort {[int]($_-split' ')[2]} -Descending?
  • 这给出了另一个结果是,但与 bash 输出不同

标签: git sorting powershell


【解决方案1】:

我的 git repos 上的 pack 目录中没有任何内容,所以我无法对此进行完全测试,但我怀疑原因是 Select-String 不返回 [string]s,它返回匹配对象.

在将命令的输出与其他命令的输出进行比较时,您必须小心使用 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 将为数组中的 each 对象提供信息(唯一的,如果它是 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 过滤。
  • 我只是尝试按照您的建议添加 % 行,但没有效果。无论我使用与否,输出都是一样的。
  • @u123 我觉得 Joey 的代码有点不对劲,应该是 Select-String | % { $_.Line },你也可以使用 Select-String | Select-Object -ExpandProperty Line 来完成。
  • 我根据您的更正进行了更新,现在我得到了其他东西,但仍然与 bash 结果不一样。
  • @briantist:在最近的 PowerShell 版本中,您只需将属性名称传递给 ForEach-Object,然后将其扩展。 (此处为 PowerShell v5)
猜你喜欢
  • 1970-01-01
  • 2021-09-07
  • 2012-09-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 2013-12-06
  • 1970-01-01
  • 2022-12-09
相关资源
最近更新 更多