2013-10-07 5 views
3

Как я могу получить PowerShell, чтобы понять этот тип вещи:Powershell: Pipe выход внешней команды к другой внешней команде

Robocopy.exe | Find.exe "Started" 

старый командный процессор дал результат, но я запутался о том, как это сделать in PowerShell:

&robocopy | find.exe "Started"    #error 
&robocopy | find.exe @("Started")    #error 
&robocopy @("|", "find.exe","Started")  #error 
&robocopy | &find @("Started")    #error 
&(robocopy | find "Started")     #error 

По существу, я хочу передать вывод одной внешней команды в другую внешнюю команду. На самом деле я буду звонить flac.exe и передать его в lame.exe для преобразования FLAC в MP3.

Приветствия

+0

Если .exe не предназначен для приема труб, вы не можете .. –

+0

Find.exe предназначен для приема труб, также как и lame.exe. Любая ошибка, которую я получаю, - это Powershell, не понимающая, что я имею в виду. Вы можете попробовать пример Find в cmd.exe – Jobbo

ответ

1

Т.Л., д-р

robocopy.exe | find.exe '"Started"' # Note the nested quoting. 

Для объяснения вложенного цитирования, читайте дальше.


PowerShell делает поддержки трубопровода и из внешних программ.

Проблемы здесь один из параметров анализа и прохождения: find.exe имеет любопытное требование, срок его поиска должен быть заключен в буквальных двойных кавычек.

В cmd.exe, просто двойные кавычки достаточно: find.exe "Started"

В отличие от PowerShell по умолчанию предварительно анализирует параметры перед передачей их на и полосы ограждающих котировки, так что find.exe видит только Started, без двойных кавычек, что приводит к ошибке.

Есть два способа решить эту проблему:

  • PS v3 + (только вариант, если ваши параметры только литералы и/или переменных окружения): специального параметра --% говорит PowerShell до передать командной строки as-is в целевую программу (переменные окружения ссылки, если таковые имеются, CMD-стиль (%<var>%)):
    robocopy.exe | find.exe --% "Started"

  • PS v2-, или если вам нужно использовать PowerShell переменные в параметрах: применить внешний слой из PowerShell со ссылкой на (PowerShell будет лишить одиночные кавычки и передать содержимое строки как есть в find.exe с ограждающими двойными кавычками нетронутых):
    robocopy.exe | find.exe '"Started"'

1

Призовите его через CMD:

PS> cmd /c 'Robocopy.exe | Find.exe "Started"' 
+0

Это работает, но если мои команды имеют много параметров, переданных им (что они делают), тогда я потеряю преимущества передающих параметров в массиве, таких как @ (,,,)? Есть ли способ сделать это без участия cmd.exe? – Jobbo

+0

Это работает, но это кошмар для чтения: & cmd @ ("/ c", @ ('robocopy', '|', 'find "Started"')) Действительно ли это компромисс между его построением все как одна строка и вложенные массивы? – Jobbo

+0

Я знаю это чувство ... Я бы написал команды длиной более одной строки в cmd-файле и выполнил его. –

1

@Jobbo: CMD и PowerShell два различных оболочек. Смешивание их иногда возможно, но, как вы поняли из ответа Шей, он не заставит вас слишком далеко. Однако вы можете задать здесь неправильный вопрос.

В большинстве случаев проблема, которую вы пытаетесь решить, например, piping to find.exe, даже не нужна. У вас есть эквивалент find.exe, на самом деле более мощная версия, в Powershell: select-string

Вы всегда можете запустить команду и присвоить результаты переменной.

$results = Robocopy c:\temp\a1 c:\temp\a2 /MIR 

Результаты будут типа STRING, и у вас есть много инструментов, чтобы нарезать и нарезать кости.

PS > $results |select-string "started" 

    Started : Monday, October 07, 2013 8:15:50 PM 
Смежные вопросы