Thử thách Powershell


7

Tôi đã bị một người bạn thách thức làm những việc sau:

"Tìm cách nhanh nhất và dễ nhất để sắp xếp danh sách thư mục theo ký tự LAST của tên tệp."

Anh ấy đã thực hiện nó trên Linux bằng cách sử dụng như sau:

ls | rev | sort | rev 

Tôi muốn cho anh ấy thấy sự thay thế quyền hạn, nhưng tôi chỉ mới bắt đầu tìm hiểu về quyền hạn và tôi không thể làm điều đó. Vì vậy, tôi đang lừa dối và nhờ bạn giúp đỡ.


1
Trên thực tế, đó là sắp xếp nó không chỉ bởi nhân vật cuối cùng mà còn bởi tất cả các nhân vật theo sau. Câu trả lời của Sam Cogan dưới đây là đúng bởi nhân vật cuối cùng và bỏ qua bất kỳ nhân vật nào sau đây.
Sim

Trước khi bất cứ ai bỏ phiếu để di chuyển câu hỏi này một lần nữa, hãy xem điều này: meta.stackexchange.com/questions/32471/iêu
raven

Tôi nghĩ rằng thách thức này là sai lệch và hơn nữa không phải là một so sánh công bằng của linux với PowerShell. Nếu rev ​​chỉ sắp xếp nhân vật cuối cùng thì sẽ công bằng. Ngoài ra, điều có thể công bằng hơn là cũng yêu cầu mọi người viết bash hoặc bất cứ điều gì để chỉ sắp xếp ký tự cuối cùng, và không chỉ đơn giản là: "ls | rev | sort | ls". Nhưng thành thật mà nói, tại sao bất cứ ai cũng muốn chức năng kỳ quặc này, tôi vẫn gãi đầu, ngoại trừ có thể cố gắng thuyết phục ai đó rằng PowerShell có thể nhỏ gọn như sh, nhưng so sánh táo với cam?
Hình elip

Câu trả lời:


3

Thật không may, Powershell không có một phương pháp đảo ngược dễ dàng, vì vậy thay vào đó bạn phải lấy chữ cái cuối cùng của chuỗi và sắp xếp theo đó. Đây là một cách tôi đã thực hiện:

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

Như đã được chỉ ra, điều này sẽ chỉ sắp xếp đúng theo chữ cái cuối cùng, trong khi phiên bản Linux tôi sẽ sắp xếp theo các chữ cái cuối cùng và sau đó, vì vậy có thể có cách tốt hơn để làm điều này hoặc bạn có thể phải giới thiệu một số vòng lặp nếu bạn muốn nó theo cách đó.


Đó là sáng chói. Không ngắn như Linux thay thế, nhưng vẫn khá tốt.
Richard

Tôi cũng nhận thấy rằng điều này chỉ sắp xếp theo chữ cái cuối cùng, không giống như phiên bản linux. Tuy nhiên, thách thức đã nêu "bởi nhân vật LAST" vì vậy câu trả lời này trả lời câu hỏi, ngay cả khi hai giải pháp không bằng nhau.
Richard

Do một số nhầm lẫn, câu hỏi này đã được chuyển sang Stack Overflow và sau đó không được chuyển đổi. Keith Hill trên Stack tràn đã thêm câu trả lời ngắn hơn ls | sort {"$ _" [- 1]}
Richard


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

Không ngắn như phiên bản unix, chủ yếu là vì không có hàm String.Reverse () trong .NET Framework. Về cơ bản, điều này hoạt động bằng cách nói sắp xếp 'sắp xếp bằng cách tính biểu thức này trên các đối số đầu vào'.


Bây giờ, nếu bất kỳ shell unix nào tốt hơn

dir | sort -Property Length -Descending

để in tất cả các tệp có tệp lớn nhất trước tiên, tôi rất muốn xem nó.


4
Thế còn 'ls -S'?
Bryan

Ồ Không biết gì về điều này: D Nice one :)
AntonioCS

2

Tôi chắc rằng ai đó có thể làm điều này tốt hơn, nhưng đây là một cách hoàn toàn tương thích với lynix. Nó có lợi ích là để lại cho bạn một revhàm chuỗi có thể sử dụng lại cho hộp công cụ của bạn, tức là nó sắp xếp toàn bộ chuỗi chứ không chỉ là ký tự cuối cùng:

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

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

Tôi nghĩ rằng các foreach ở đây chứng minh độc đáo cách các ống PowerShell là các mảng và không chỉ đơn giản là các chuỗi như trong * nix.

Phải mất một lúc tôi mới nhận ra rằng tôi phải sử dụng duy nhất $_và không sử dụng $_.namethứ 2 foreach. Vì vậy, tôi đã học được điều gì đó về các biến thể trong nội dung mảng từ ống này sang ống khác.

* Tín dụng cho sự can đảm của chức năng rev của tôi vào http://rosettacode.org/wiki/Reverse_a_opes#PowerShell


Hoạt động như lynix:

  • thư mục | sắp xếp -Property @ {Expression = {$ n = $ _. Name.ToCharArray (); [Mảng] :: Đảo ngược ($ n); [Chuỗi] :: Tham gia ("", $ n)}}

Sắp xếp các tác phẩm như lynix, nhưng rất, rất chậm:

  • ls -n | sắp xếp {$ _ [3e3..0]}

Không hoạt động như lynix, tức là không sắp xếp tất cả các ký tự của tên tệp; (chỉ sắp xếp ký tự cuối cùng của chuỗi):

  • thư mục | sắp xếp {$ .name.Sub chuỗi ($ .name.length-1)}
  • thư mục | sắp xếp {$ _. name [-1]}
  • ls | sắp xếp {$ _. Tên [-1]}
  • ls | sắp xếp {"$ _" [- 1]}
  • ls -n | sắp xếp {$ _ [- 1]}

Điều này có thể được cải thiện bằng cách làm cho hàm rev chấp nhận một mảng. Sau đó, bạn có thể loại bỏ forEach trong mã, vì hàm sẽ gọi nó. Bạn có thể thêm một vài điều để làm cho nó ls | rev | sort | revhoàn toàn hợp lệ. :-)
Cory Knutson

1

Biến thể của Shay ngắn hơn câu trả lời được chấp nhận bằng cách lập chỉ mục vào chuỗi nhưng thậm chí điều đó có thể được cải thiện. Bạn có thể rút ngắn nó hơn nữa bằng cách loại trừ các khoảng trắng không cần thiết và sử dụng bí danh ngắn hơn:

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

Ngoài ra, bạn có thể sử dụng -Nameđối số (viết tắt) để Get-ChildItem:

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

sẽ trả lại chuỗi trực tiếp.

Nếu bạn thực sự muốn sắp xếp theo chuỗi ngược lại , thì các công việc sau (nhưng chậm):

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

Bạn có thể làm cho nó nhanh hơn nếu bạn có giới hạn trên về độ dài của tên tệp.


Trích dẫn từ câu hỏi: »Tìm cách nhanh nhất và dễ nhất để sắp xếp danh sách thư mục theo ký tự LAST của tên tệp.«. Nó chỉ cần sắp xếp theo ký tự cuối cùng. Nếu cách dễ nhất để làm như vậy là đảo ngược chuỗi, thì cũng vậy, nhưng nếu cách dễ nhất để làm như vậy chỉ bằng cách sắp xếp theo ký tự cuối cùng, thì điều này cũng giải quyết được nhiệm vụ. Câu hỏi không phải là về »Làm cách nào tôi có thể thực hiện đoạn mã vỏ Unix này giống hệt nhau trong PowerShell?«.
Joey

Lấy làm tiếc. Tôi đã hiểu sai.
Hình elip

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.