Как мне написать скрипт PowerShell, который принимает конвейерный ввод? - PullRequest
73 голосов
/ 20 мая 2009

Я пытаюсь написать сценарий PowerShell, который может получать данные конвейера (и, как ожидается, будет делать это), но пытается что-то вроде

ForEach-Object {
   # do something
}

на самом деле не работает при использовании сценария из командной строки следующим образом:

1..20 | .\test.ps1

Есть ли способ?

Примечание: я знаю о функциях и фильтрах. Это не то, что я ищу.

Ответы [ 4 ]

109 голосов
/ 20 мая 2009

В v2 вы также можете принимать входные данные конвейера (по свойству propertyName или byValue), добавлять псевдонимы параметров и т. Д .:

function Get-File{
    param(  
    [Parameter(
        Position=0, 
        Mandatory=$true, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true)
    ]
    [Alias('FullName')]
    [String[]]$FilePath
    ) 

    process {
       foreach($path in $FilePath)
       {
           Write-Host "file path is: $path"
       }
    }
}


# test ValueFromPipelineByPropertyName 
dir | Get-File

# test ValueFromPipeline (byValue) 

"D:\scripts\s1.txt","D:\scripts\s2.txt" | Get-File

 - or -

dir *.txt | foreach {$_.fullname} | Get-File
38 голосов
/ 20 мая 2009

Это работает, и, возможно, есть другие способы сделать это:

foreach ($i in $input) {
    $i
}

17: 12: 42 PS> 1,20 | . \ CMD-input.ps1
1
2
3
- snip -
18
19
20

Найдите «powershell $ input variable», и вы найдете больше информации и примеров.
Пара здесь:
Функции и фильтры PowerShell PowerShell Pro!
(см. раздел «Использование специальной переменной PowerShell« $ input ») *
«Все сценарии, функции и блоки сценариев имеют доступ к переменной $ input, которая обеспечивает перечислитель для элементов входящего конвейера».
или
$ input гласит: «PowerBlog Дмитрия PowerShell и более поздние версии»
«... в основном $ input в перечислителе, который обеспечивает доступ к имеющемуся у вас конвейеру.»

Для командной строки PS, а не для командной строки DOS Командный процессор Windows.

23 голосов
/ 20 мая 2009

Вы можете написать фильтр, который является частным случаем функции, например:

filter SquareIt([int]$num) { $_ * $_ }

или вы можете создать аналогичную функцию следующим образом:

function SquareIt([int]$num) {
  Begin {
    # Executes once before first item in pipeline is processed
  }

  Process {
    # Executes once for each pipeline object
    $_ * $_
  }

  End {
    # Executes once after last pipeline object is processed
  }
}

Вышеуказанное работает как определение интерактивной функции или если сценарий может быть добавлен в ваш глобальный сеанс (или другой сценарий). Однако ваш пример показал, что вы хотели сценарий, так что здесь он находится в сценарии, который можно использовать напрямую (не нужно расставлять точки):

  --- Contents of test.ps1 ---
  param([int]$num)

  Begin {
    # Executes once before first item in pipeline is processed
  }

  Process {
    # Executes once for each pipeline object
    $_ * $_
  }

  End {
    # Executes once after last pipeline object is processed
  }

В PowerShell V2 это немного меняется с помощью «расширенных функций», которые включают функции с теми же функциями привязки параметров, что и скомпилированные командлеты. См. сообщение в блоге для примера различий. Также обратите внимание, что в этом случае расширенных функций вы не используете $ _ для доступа к объекту конвейера. С помощью расширенных функций объекты конвейера связываются с параметром так же, как и с командлетом.

7 голосов
/ 09 августа 2012

Ниже приведены простейшие возможные примеры скриптов / функций, которые используют ввод по каналу. Каждый из них ведет себя так же, как конвейер для командлета "echo".

Как скрипты:

# Echo-Pipe.ps1
  Begin {
    # Executes once before first item in pipeline is processed
  }

  Process {
    # Executes once for each pipeline object
    echo $_
  }

  End {
    # Executes once after last pipeline object is processed
  }
# Echo-Pipe2.ps1
foreach ($i in $input) {
    $i
}

Как функции:

Function Echo-Pipe {
  Begin {
    # Executes once before first item in pipeline is processed
  }

  Process {
    # Executes once for each pipeline object
    echo $_
  }

  End {
    # Executes once after last pipeline object is processed
  }
}

Function Echo-Pipe2 {
    foreach ($i in $input) {
        $i
    }
}

1010 * Е.Г. *

PS > . theFileThatContainsTheFunctions.ps1 # This includes the functions into your session
PS > echo "hello world" | Echo-Pipe
hello world
PS > cat aFileWithThreeTestLines.txt | Echo-Pipe2
The first test line
The second test line
The third test line
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...