Tantangan Powershell


7

Saya ditantang oleh seorang teman untuk melakukan hal berikut:

"Temukan cara tercepat dan termudah untuk menyortir daftar direktori berdasarkan karakter nama file TERAKHIR."

Dia melakukannya di Linux menggunakan yang berikut:

ls | rev | sort | rev 

Saya ingin menunjukkan kepadanya alternatif powershell, tapi saya baru saja mulai mempelajari powershell dan saya tidak bisa melakukannya. Jadi, saya selingkuh dan meminta bantuan Anda.


1
Sebenarnya itu bukan hanya menyortir karakter terakhir tetapi juga semua karakter berikut. Jawaban Sam Cogan di bawah ini sepenuhnya oleh karakter terakhir dan mengabaikan semua karakter berikut.
Sim

Sebelum ada orang yang memilih untuk memigrasikan pertanyaan ini lagi, lihat ini: meta.stackexchange.com/questions/32471/…
raven

Saya pikir tantangan ini menyesatkan dan lebih jauh lagi bukan perbandingan linux yang adil dengan PowerShell. Jika rev hanya mengurutkan karakter terakhir maka itu akan adil. Juga apa yang mungkin lebih adil adalah meminta orang untuk menulis bash atau apa pun untuk hanya mengurutkan karakter terakhir, dan tidak hanya melakukan: "ls | rev | sort | ls". Tapi jujur, mengapa ada orang yang ingin fungsi aneh ini aku masih menggaruk-garuk kepalaku, kecuali mungkin untuk mencoba dan meyakinkan seseorang bahwa PowerShell bisa sekompak sh, tetapi dengan perbandingan apel dengan jeruk?
Tampilan elips

Jawaban:


3

Sayangnya Powershell tidak memiliki metode pembalikan yang mudah dan menyenangkan, jadi alih-alih Anda harus mendapatkan huruf terakhir dari string dan mengurutkannya. Ini adalah salah satu cara saya melakukannya:

dir| sort {$_.name.Substring($_.name.length-1)}

Seperti yang telah ditunjukkan, ini hanya akan diurutkan berdasarkan huruf terakhir saja, sedangkan saya versi Linux akan mengurutkan berdasarkan huruf terakhir dan selanjutnya, jadi mungkin ada cara yang lebih baik untuk melakukan ini, atau Anda mungkin harus memperkenalkan beberapa perulangan jika Anda menginginkannya seperti itu.


Itu brill. Tidak sesingkat alternatif Linux, tetapi masih cukup bagus.
Richard

Saya perhatikan juga bahwa ini hanya mengurutkan berdasarkan huruf terakhir, tidak seperti versi linux. Namun tantangannya dinyatakan "oleh karakter TERAKHIR" jadi jawaban ini menjawab pertanyaan, meskipun kedua solusi tidak sama.
Richard

Karena beberapa kebingungan pertanyaan ini dimigrasikan ke Stack Overflow dan kemudian tidak bermigrasi. Keith Hill on Stack overflow menambahkan jawaban yang lebih pendek ls | sort {"$ _" [- 1]}
Richard


2
dir | sort -Property @{Expression ={$n = $_.Name.ToCharArray(); [Array]::Reverse($n);[String]::Join("",$n)}}

Tidak sesingkat versi unix, sebagian besar karena tidak ada fungsi String.Reverse () di .NET Framework. Pada dasarnya ini bekerja dengan mengatakan sort 'sort by computing ekspresi ini pada argumen input'.


Sekarang, jika ada shell unix yang lebih baik dari

dir | sort -Property Length -Descending

untuk mencetak semua file dengan yang terbesar terlebih dahulu, saya akan tertarik melihatnya.


4
Bagaimana dengan 'ls -S'?
Bryan

Wow! Tidak tahu tentang yang satu ini: D Nice one :)
AntonioCS

2

Saya yakin seseorang dapat melakukan ini dengan lebih baik, tetapi di sini ada satu cara yang sepenuhnya kompatibel dengan lynix. Ini memiliki keuntungan meninggalkan Anda dengan revfungsi string yang dapat digunakan kembali untuk kotak peralatan Anda, yaitu mengurutkan seluruh string dan bukan hanya karakter terakhir:

function rev ($s) {return -join ($s[$s.Length..0])}

dir | foreach{rev($_.name)} | sort | foreach{rev($_)}

Saya pikir pendahuluan di sini dengan baik menunjukkan bagaimana pipa PowerShell adalah array dan bukan hanya string seperti di * nix.

Butuh beberapa saat untuk menyadari bahwa saya harus menggunakan saja $_dan tidak $_.namedi dalam ke-2 foreach. Jadi saya telah belajar sesuatu tentang variasi konten array dari satu pipa ke yang berikutnya.

* Kredit untuk nyali fungsi rev saya masuk ke http://rosettacode.org/wiki/Reverse_a_string#PowerShell


Bekerja seperti lynix:

  • dir | sort -Property @ {Expression = {$ n = $ _. Name.ToCharArray (); [Array] :: Balikkan ($ n); [String] :: Gabung ("", $ n)}}

Semacam karya seperti lynix, tetapi sangat, sangat lambat:

  • ls -n | sort {$ _ [3e3..0]}

Jangan bekerja seperti lynix, yaitu gagal mengurutkan semua karakter dari nama file; (hanya mengurutkan karakter terakhir dari string):

  • dir | sortir {$ .name.Substring ($ .name.length-1)}
  • dir | sortir {$ _. name [-1]}
  • ls | sort {$ _. Name [-1]}
  • ls | sort {"$ _" [- 1]}
  • ls -n | sort {$ _ [- 1]}

Ini dapat ditingkatkan dengan membuat fungsi rev menerima array. Kemudian Anda bisa menghilangkan forEach dalam kode, sebagaimana fungsi akan menyebutnya. Anda dapat menambahkan beberapa hal untuk menjadikannya ls | rev | sort | revbenar - benar valid sendiri. :-)
Cory Knutson

1

Varian Shay jauh lebih pendek dari jawaban yang diterima dengan mengindeks ke dalam string tetapi bahkan itu dapat ditingkatkan. Anda dapat mempersingkat lebih banyak lagi dengan mengecualikan ruang yang tidak perlu dan menggunakan alias lebih pendek:

ls|sort{$_.Name[-1]}

Anda juga dapat menggunakan -Nameargumen (disingkat) untuk Get-ChildItem:

ls -n|sort{$_[-1]}

yang akan mengembalikan string secara langsung.

Jika Anda benar-benar ingin mengurutkan berdasarkan string terbalik , maka yang berikut berfungsi (tetapi lambat):

ls -n|sort{$_[3e3..0]}

Anda dapat membuatnya lebih cepat jika Anda memiliki batas atas pada panjang nama file.


Mengutip dari pertanyaan: »Temukan cara tercepat dan termudah untuk menyortir daftar direktori berdasarkan karakter TERAKHIR dari nama file.«. Itu hanya perlu mengurutkan berdasarkan karakter terakhir. Jika cara termudah untuk melakukannya adalah membalikkan string, biarlah, tetapi jika cara termudah untuk melakukannya adalah dengan hanya mengurutkan berdasarkan karakter terakhir, maka ini menyelesaikan tugas juga. Pertanyaannya bukan tentang »Bagaimana saya bisa melakukan potongan Unix shell ini persis sama di PowerShell?«.
Joey

Maaf. Saya salah.
Tampilan elips

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.