Що означає $ _ в PowerShell?


226

Я багато що бачив у PowerShell, але що це робить саме?

$_

5
На це питання, звичайно, відповіли за окремим даним лексемою, але на стіновій схемі, що ілюструє всі спеціальні лексеми PowerShell, подивіться Повне керівництво по пунктуації PowerShell
Майкл Соренс

Відповіді:


171

Це змінна для поточного значення в трубопроводі, яка називається $PSItemв Powershell 3 і новішою.

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

або

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

Наприклад, у наведеному вище коді %{}блок викликається для кожного значення масиву. $_Або $PSItemзмінна буде містити поточне значення.


42
Це не обов'язково пов'язано з трубопроводом. Це більше "поточний аргумент до поточного блоку сценарію". Наприклад, поки ви можете використовувати його просто чудово ForEach-Objectабо Where-Objectви не можете використовувати його в чомусь подібному Get-Foo|Add-Member NoteProperty Bar ($_.SomeProperty)- тут є конвеєр, але немає блоку сценаріїв і, отже, немає $_. (Як було сказано, довідка PowerShell також посилається на трубопровід для $_. Заплутаність.)
Joey

@Joey, ти можеш абсолютно використовувати $ _ у своєму прикладі. Get-Foo | Add-Member -Type NoteProperty -Name Bar -Value $_.SomeProperty
Xalorous

@Xalorous: Тільки тому, що вона не створює помилки, не означає, що вона працює: Get-ChildItem | Add-Member -Type NoteProperty -Name Bar -Value $_.Name -PassThru | Select Bar... Ну, це може працювати, якщо у вас є $_область, де ви виконуєте цей конвеєр. Але це дуже відрізняється від того, що ти зазвичай маєш на увазі, намагаючись написати щось подібне.
Joey

@Joey $_у тому, що ви написали, чомусь не перебирає усі об'єкти. Спробуйте це замість цього. gci | % { $_ | add-member -Type NoteProperty -Name Bar -Value $_.name -PassThru } | Select Bar. Я підозрюю, що gci | cmdletбез явного передбачення збирає результати gci і передає масив командлету. Однак масив є об’єктом, тому він додає властивість до об’єкта масиву. У масиві немає властивості 'name', тому значення, присвоєне $ _. Бар є $ null. Підсумок полягає в тому, що $ _ широко використовується з / по трубопроводу. Не потрібно% {} для перегляду циклу - це нове.
Xalorous

Робоча версія з видаленим додатковим трубопроводом. gci | % { add-member -InputObject $_ -Type NoteProperty -Name Bar -Value $_.name -PassThru } | Select Bar
Xalorous

37

Я думаю, що найпростіший спосіб подумати про цю змінну, як вхідний параметр у лямбда-виразі в C #. Тобто $_аналогічно xв x => Console.WriteLine(x)анонімній функції в C #. Розглянемо наступні приклади:

PowerShell:

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

Друкує:

1
2
3

або

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

Друкує:

2
3

І порівняйте це з синтаксисом C # за допомогою LINQ:

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

Друкує:

1
2
3

або

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

Друкує:

2
3

6
У C # не використовуйте _як вхідний параметр лямбда. _іноді використовується при ігноруванні параметрів, замість цього використовуйте x. stackoverflow.com/questions/424775/…
Carlos Muñoz

28

За даними цього веб-сайту, це посилання this, в основному, на циклі.

$ _ (підкреслення долара) маркер 'ЦЕ'. Зазвичай відноситься до предмета всередині петлі переднього плану. Завдання: надрукувати всі елементи колекції. Рішення. ... | foreach {Write-Host $ _}


3
thisє досить заплутаним терміном для $_змінної. В OOP він зазвичай посилається на клас, а не на змінну.
окт

1
@remco, особливо коли PS v5 додає цю змінну $ для використання в класах.
Xalorous


1

$ _ - це змінна, яка повторюється над кожним об'єктом / елементом, переданим з попереднього | (труба).


1

$_являє собою змінну, створену системою, як правило, всередині виразів блоків, на які посилаються командлети, які використовуються з трубою, такою як Where-Objectі ForEach-Object.

Але його можна використовувати і в інших видах виразів, наприклад, у Select-Objectпоєднанні з властивостями експресії. Get-ChildItem | Select-Object @{Name="Name";Expression={$_.Name}}. У цьому випадку $_представляє елемент, який перебуває в трубі, але може існувати декілька виразів.

На нього можна також посилатись за допомогою валідації спеціальних параметрів, де блок скриптів використовується для перевірки значення. У цьому випадку a $_представляє значення параметра, отримане від виклику.

Найближча аналогія c # і java - це вираз lamda. Якщо ви розбиваєте повноваження на основи, то все є блоком скриптів, включаючи файл сценарію a, функції та командлети. Ви можете визначити власні параметри, але в деяких випадках система створюється для вас, яка представляє елемент введення для обробки / оцінки . У таких ситуаціях автоматична змінна є $_.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.