2

単純な構造のテキストファイルがあります。これは実際にはftpのコンテンツです。

1.0
1.0a
10.0
10.0b
11.0
11.0f
2.0
3.0
4.0
...(and so on)
random string
random string

get-contentを使用してファイルのコンテンツを取得していますが、最大数と最大1の数を含む行のみを取得できるようにしたいと考えています。この場合、たとえば、次のように返します。

10.0
10.0b
11.0
11.0f

sort-objectを使用してみましたが、機能しませんでした。ソートオブジェクトをそのような方法で使用して、文字列ではなく数値をソートしていることを認識し(1の後に10を配置しないように)、ピリオドの前の数字に従ってソートし、ランダムを無視する方法はありますか?最後に文字列をまとめて...

または、提案する別の方法がある場合は、そうしてください...ありがとうございます。

4

2 に答える 2

2

スクリプトブロックを一部のコマンドレット(この場合はSort-Objectおよび)に渡すことができGroup-Objectます。もう少し明確にするために:

  1. データをロードする

    Get-Content foo.txt |
    
  2. 番号でグループ化します(接尾辞が存在する場合は無視します):

        Group-Object { $_ -replace '\..*$' } |
    

    これにより、最初に文字列の末尾にある数字以外の数字が削除され、文字列の残りの部分(できれば浮動小数点数のみが含まれるようになります)がグループ名として使用されます。

  3. そのグループ名で数値で並べ替えます。

        Sort-Object { [int] $_.Name } |
    

    これは、元の行から派生したものでグループ化したのと同じように、グループの名前を数値に変換して並べ替えるだけで実行できます。

  4. 次に、最後の2つのグループを取得します。これは、最大数と最大数から2番目の数のすべての行を表し、グループをアンラップします。-Lastパラメータはかなり自明で-ExpandPropertyあり、フィルタリングされたプロパティリストを使用して新しいオブジェクトを作成する代わりに、プロパティの値を選択します。

        Select-Object -Last 2 -ExpandProperty Group
    

そして、そこにあります。このパイプラインをさまざまな段階で試して、コマンドの目的を理解することができます。

PS Home:\> gc foo.txt
1.0
1.0a
10.0
10.0b
11.0
11.0f
2.0
3.0
4.0

PS Home:\> gc foo.txt | group {$_ -replace '\..*$'}

Count Name                      Group
----- ----                      -----
    2 1.0                       {1.0, 1.0a}
    2 10.0                      {10.0, 10.0b}
    2 11.0                      {11.0, 11.0f}
    1 2.0                       {2.0}
    1 3.0                       {3.0}
    1 4.0                       {4.0}

PS Home:\> gc foo.txt | group {$_ -replace '\..*$'} | sort {[int]$_.Name}

Count Name                      Group
----- ----                      -----
    2 1.0                       {1.0, 1.0a}
    1 2.0                       {2.0}
    1 3.0                       {3.0}
    1 4.0                       {4.0}
    2 10.0                      {10.0, 10.0b}
    2 11.0                      {11.0, 11.0f}

PS Home:\> gc foo.txt | group {$_ -replace '\..*$'} | sort {[int]$_.Name} | select -l 2 -exp group
10.0
10.0b
11.0
11.0f

グループ内のアイテム(および最後の2つのグループの最終結果)がサフィックスでソートされている必要がある場合は、のSort-Object直後に別のアイテムを貼り付けることができますGet-Content

于 2012-04-29T10:39:03.273 に答える
0

式をに渡すことができSort-Objectます。並べ替えでは、その式を使用してオブジェクトを並べ替えます。expressionこれは、キー(と省略可能)を含むハッシュテーブルを渡すことによって行われますedescending順序を逆にするには、値がの2番目のキー(またはd)を追加します$true

あなたの場合

...input... | Sort @{e={convert $_ as required}}

複数のプロパティ名とハッシュテーブルを指定できるため11.0f、数値とサフィックスに分割できます。

並べ替え式の間に多くの重複がある場合は、最初に並べ替えプロパティを使用してオブジェクトへの入力を前処理することができます(その後削除します)。

...input... | %{ 
  if ($_ -match '^(\d+\.0)(.)?') {
    new-object PSObject -prop @{value=$_; a=[double]::Parse($matches[1]); b=$matches[2] }
  } else {
    new-object PSObject -prop @{value=$_; a=[double]::MinValue; b=$null }
  }
} | sort a,b | select -expand value
于 2012-04-29T10:08:13.433 に答える