web-dev-qa-db-ja.com

PowerShellのxargsに相当するものは何ですか?

POSIX定義のxargs コマンドは、標準入力から受け取ったすべての項目を受け取り、独自のコマンドラインで受け取ったコマンドにコマンドライン引数として渡します。例:grep -rn "String" | xargs rm

PowerShellで同等のものは何ですか?

次の質問はすべてこれを尋ねます:

ただし、すべての回答がForEach-Objectを使用するため、正解はありません。これは、一度に1つずつアイテムを処理する(xargs -n1など)ので、指定された例で望ましい結果が得られるか、または変数の中間結果。これは、機能的なコマンドラインfuを怒らせます。

32
simonwo

私が見つけた方法は2つあります。 1つ目はおそらくより慣用的なPowerShellであり、2つ目はxargsのパイプベースの精神により忠実です。

例として、すべての猫の写真を_myapp.exe_に渡したいとしましょう。

方法#1:コマンド置換

コマンド文字列にパイプラインを埋め込むことにより、shで$(コマンド置換)を使用するのと同じようなことができます。

_&"myapp.exe" @(Get-ChildItem -Recurse -Filter *.jpg | Another-Step)
_

@(...)は、その中のコマンドから配列を作成し、PowerShellは_&_に渡された配列を個別のコマンドラインパラメーターに自動的に拡張します。

ただし、これは実際には質問に答えません。渡したいコマンドを制御できる場合にのみ機能するためです。そうでない場合もあります。

方法2:真の配管

また、オブジェクトをパイプ処理するためのサブ式を作成し、それらを配列に収集して、配列を最終的なコマンドにパイプ処理することにより、「二重パイプライン」を構築することもできます。

_,@(Get-ChildItem -Recurse -Filter *.jpg | Another-Step) | %{&"myapp.exe" $_}
_

前と同じように@(...)はアイテムを配列に収集し、その配列は_%_(_ForEach-Object_)を使用して呼び出される最後のコマンドにパイプされます。通常、PowerShellはパイプ処理された配列を自動的にフラット化するため、これは各項目を個別にループしますが、_,_演算子を前に付けることで回避できます。次に、_$__特殊変数を通常どおり使用して、渡された配列を埋め込みます。

したがって、重要なのは、収集するパイプラインを,@(...)でラップし、それを_%{...}_の何かにパイプすることです。

27
simonwo