Saring daftar string dalam PowerShell oleh regex, lalu kelompokkan dan urutkan berdasarkan salah satu kelompok tangkapan

0

Saya mencari cara untuk memfilter daftar string di PowerShell oleh regex, lalu kelompokkan dan urutkan berdasarkan salah satu kelompok tangkapan.

Bayangkan daftar saya seperti ini:

bogus0
ACBXYZ-0000 hello
bogus1
ACBXYZ-0000 hello again
bogus2
ACBXYZ-0001 world
bogus3
ACBXYZ-0001 world

Pertama saya melakukan ini:

$list | select-string "^(ACBXYZ-\d+)(.*)"

Output yang mana

ACBXYZ-0000 hello
ACBXYZ-0000 hello again
ACBXYZ-0001 world
ACBXYZ-0001 world

Maka saya telah melakukan ini:

$list | select-string "^(ACBXYZ-\d+)(.*)" | % { "$($_.Matches[0].Groups[1].Value), $($_.Matches[0].Groups[2].Value.Trim(' ,-'))" } | sort | group | select name

Output yang mana

Name
----
ACBXYZ-0000, hello
ACBXYZ-0000, hello again
ACBXYZ-0001, world

Tapi sebenarnya saya ingin menampilkan ini:

Name
----
ACBXYZ-0000, hello
ACBXYZ-0001, world

karena pesan setelah nomornya bagus untuk dimiliki tetapi tidak terlalu penting.

Ada ide?

PS: Saya bisa mencapainya dengan skrip yang lebih rumit, tetapi saya mencari satu-liner.

Alex
sumber

Jawaban:

0

Yang Anda butuhkan adalah tabel hash untuk menyimpan hasil Anda. Tabel hash adalah kumpulan pasangan kunci-nilai. Dalam kasus Anda, kunci akan menjadi string "ACBXYZ-0000", dan nilainya akan menjadi string "halo". Kunci dalam tabel hash adalah unik, yang persis apa yang kita butuhkan di sini.

Sebagai contoh:

$myHash = @{}
$myHash["ACBXYZ-0001"] = "hi there"  # set a value
Write-Output $myHash["ACBXYZ-0001"]  # retrieve the value

Saya telah menulis ulang skrip Anda untuk menggunakan tabel hash di sini:

$list = gc text.txt
$out = @{}
$list | select-string "^(ACBXYZ-\d+)(.*)" | 
    % { $out[$_.Matches[0].Groups[1].Value] = $_.Matches[0].Groups[2].Value.Trim(' ,-') }
$out 

Itu memberikan ini:

Name                           Value                                                                                                           
----                           -----                                                                                                           
ACBXYZ-0000                    hello again                                                                                                     
ACBXYZ-0001                    world                                                                                                           

Anda dapat melihat bahwa "ACBXYZ-0000" kedua telah menimpa yang pertama. Jika Anda tidak suka itu, Anda dapat memeriksa sebelum menyimpan kunci untuk melihat apakah itu ada di tabel hash dengan $out.ContainsKey().

Saya akan menyerahkan kepada Anda untuk mengetahui cara menampilkan hasil sebagai daftar string yang diurutkan. Beri tahu saya jika Anda memiliki masalah.

Hanya untuk bersenang-senang, saya juga menulis ulang skrip Anda untuk lebih banyak tentang bagaimana saya akan melakukannya:

$list = gc text.txt
$out = @{}
$list | % {
    if ($_ -match "^(ACBXYZ-\d+)(.*)") 
    { 
        $out[$matches[1]] = $matches[2].Trim(' ,-') 
    } 
}
$out
dangph
sumber