$ _ Có nghĩa là gì trong PowerShell?


226

Tôi đã thấy rất nhiều điều sau đây trong PowerShell, nhưng chính xác thì nó làm gì?

$_

5
Tất nhiên, câu hỏi đã được trả lời cho một mã thông báo đặc biệt được đưa ra, nhưng đối với một wallchart minh họa tất cả các mã thông báo đặc biệt của PowerShell, hãy xem Hướng dẫn hoàn chỉnh về chấm câu PowerShell
Michael Sorens

Câu trả lời:


171

Đây là biến cho giá trị hiện tại trong đường ống, được gọi $PSItemtrong Powershell 3 và mới hơn.

1,2,3 | %{ write-host $_ } 

hoặc là

1,2,3 | %{ write-host $PSItem } 

Ví dụ trong đoạn mã trên, %{}khối được gọi cho mọi giá trị trong mảng. Biến $_hoặc $PSItemsẽ chứa giá trị hiện tại.


42
Nó không nhất thiết liên quan đến đường ống. Đó là một "đối số hiện tại cho khối tập lệnh hiện đang thực thi". Ví dụ: trong khi bạn có thể sử dụng nó tốt ForEach-Objecthoặc Where-Objectbạn không thể sử dụng nó trong một cái gì đó như Get-Foo|Add-Member NoteProperty Bar ($_.SomeProperty)- có một đường ống liên quan, nhưng không có khối kịch bản và do đó không $_. (Điều đó đang được nói, trợ giúp PowerShell cũng đề cập đến đường ống dẫn $_. Khó hiểu.)
Joey

@ Bạn hoàn toàn có thể sử dụng $ _ trong ví dụ của mình. Get-Foo | Add-Member -Type NoteProperty -Name Bar -Value $_.SomeProperty
Xalious 6/11/2015

@Xalious: Chỉ vì nó không tạo ra lỗi không có nghĩa là nó hoạt động: Get-ChildItem | Add-Member -Type NoteProperty -Name Bar -Value $_.Name -PassThru | Select Bar... Chà, nó có thể hoạt động nếu bạn có $_trong phạm vi mà bạn đang thực hiện đường ống đó. Nhưng điều đó rất khác so với những gì bạn thường nói khi cố gắng viết một cái gì đó như thế.
Joey

@ Vì vậy, $_trong những gì bạn đã viết, vì một số lý do, không lặp qua tất cả các đối tượng. Hãy thử điều này thay thế. gci | % { $_ | add-member -Type NoteProperty -Name Bar -Value $_.name -PassThru } | Select Bar. Tôi nghi ngờ rằng việc gci | cmdletkhông có foreach rõ ràng sẽ thu thập kết quả gci và chuyển một mảng cho lệnh ghép ngắn. Tuy nhiên, mảng là một đối tượng, vì vậy nó thêm một thuộc tính vào đối tượng mảng. Mảng không có thuộc tính 'name', vì vậy giá trị được gán cho $ _. Bar là $ null. Điểm mấu chốt là $ _ được sử dụng rộng rãi w / pipelining. Không cần% {} để lặp qua là mới.
Xalious

Phiên bản làm việc với đường ống phụ được gỡ bỏ. gci | % { add-member -InputObject $_ -Type NoteProperty -Name Bar -Value $_.name -PassThru } | Select Bar
Xalious

37

Tôi nghĩ cách dễ nhất để suy nghĩ về biến này như tham số đầu vào trong biểu thức lambda trong C #. Tức $_là tương tự như xtrong x => Console.WriteLine(x)chức năng ẩn danh trong C #. Xem xét các ví dụ sau:

PowerShell:

1,2,3 | ForEach-Object {Write-Host $_}

Bản in:

1
2
3

hoặc là

1,2,3 | Where-Object {$_ -gt 1}

Bản in:

2
3

Và so sánh điều này với cú pháp C # bằng LINQ:

var list = new List<int> { 1, 2, 3 };
list.ForEach( _ => Console.WriteLine( _ ));

Bản in:

1
2
3

hoặc là

list.Where( _ => _ > 1)
    .ToList()
    .ForEach(s => Console.WriteLine(s));

Bản in:

2
3

6
Trong C # không sử dụng _làm tham số đầu vào trong lambda. _đôi khi được sử dụng khi các tham số bị bỏ qua, thay vào đó sử dụng x. stackoverflow.com/questions/424775/ Mạnh
Carlos Muñoz

28

Theo trang web này , nó là một tài liệu tham khảo this, chủ yếu là các vòng lặp.

$ _ (đô la gạch dưới) mã thông báo 'NÀY'. Thông thường đề cập đến các mục bên trong một vòng lặp foreach. Nhiệm vụ: In tất cả các mục trong một bộ sưu tập. Giải pháp. ... | foreach {Viết-lưu trữ $ _}


3
thislà một thuật ngữ khá khó hiểu cho $_biến. Trong OOP, nó thường đề cập đến lớp, không phải là một biến.
oɔɯǝɹ 6/11/2015

1
@remco đặc biệt là khi PS v5 thêm $ biến này để sử dụng trong các lớp.
Xalious 6/11/2015


1

$ _ là một biến lặp qua từng đối tượng / phần tử được truyền từ trước đó | (ống).


1

$_là một biến được tạo bởi hệ thống thường bên trong các biểu thức khối được tham chiếu bởi các lệnh ghép ngắn được sử dụng với đường ống như Where-ObjectForEach-Object.

Nhưng nó cũng có thể được sử dụng trong các loại biểu thức khác, ví dụ như Select-Objectkết hợp với các thuộc tính biểu thức. Get-ChildItem | Select-Object @{Name="Name";Expression={$_.Name}}. Trong trường hợp này, $_đại diện cho mục được dẫn nhưng nhiều biểu thức có thể tồn tại.

Nó cũng có thể được tham chiếu bằng xác thực tham số tùy chỉnh, trong đó một khối tập lệnh được sử dụng để xác thực một giá trị. Trong trường hợp này, $_đại diện cho giá trị tham số như nhận được từ lời gọi.

Sự tương tự gần nhất với c # và java là biểu thức lamda. Nếu bạn chia nhỏ quyền hạn thành cơ bản thì mọi thứ là một khối tập lệnh bao gồm tệp tập lệnh a, hàm và lệnh ghép ngắn. Bạn có thể xác định các tham số của riêng mình nhưng trong một số trường hợp, một hệ thống được tạo bởi bạn đại diện cho mục đầu vào để xử lý / đánh giá . Trong những tình huống đó, biến tự động là $_.

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.