私は並列に多くのコマンドを実行しようとしていますが、まず入力に対して何らかの文字列操作を行う必要があります。下の例はどのように動作させることができますか?引数をxargsからbashに渡して処理の変数として受け取ります
find . -mindepth 1 -type d | xargs -n 1 -P 20 -i sh -c "v={}; echo $v"
これを使用すると、$v
はnullです。 {}
の値として保存されないのはなぜですか?
私は並列に多くのコマンドを実行しようとしていますが、まず入力に対して何らかの文字列操作を行う必要があります。下の例はどのように動作させることができますか?引数をxargsからbashに渡して処理の変数として受け取ります
find . -mindepth 1 -type d | xargs -n 1 -P 20 -i sh -c "v={}; echo $v"
これを使用すると、$v
はnullです。 {}
の値として保存されないのはなぜですか?
$v
の前にの文字列がxargs
に渡されます。
find
コマンドでサブディレクトリ./stuff
が見つかったとします。
最初に親のbash
シェル(find
コマンドを入力したシェル)は、文字列が二重引用符で囲まれているため、$v
を展開します。変数v
に現在値が設定されていないため、空の文字列に展開されます。
次に、引数はこの表示されますこれは、xargs
に渡されます:次にv={}; echo
を、xargs
がパイプから./stuff
を読んで、そして最後に、sh
コマンドがで実行される./stuff
で{}
を交換しますxargs
およびsh
は次のようになります。v=./stuff; echo
この問題を解決するには、$
のようにして、親シェルが展開しないようにするか、単一引用符を使用して変数展開を回避します。彼らにスペースを持つ任意のディレクトリ名が最終sh
コマンドで問題を起こさないように、あなたはまた、おそらく文字列を引用符で囲む必要があります。
find . -mindepth 1 -type d | xargs -n 1 -P 20 -i sh -c "v=\"{}\"; echo \"\$v\""
OR
find . -mindepth 1 -type d | xargs -n 1 -P 20 -i sh -c 'v="{}"; echo "$v"'
コマンドのいずれかを使用すると、最終的sh
プロセスをv="./stuff"; echo "$v"
ちなみに、実際に起こっていることを自分自身で確認する方法の1つは、親シェルでv
の値を設定してから実行します元のコマンド。シェルは$v
を任意の値に展開し、その値がfind
で見つかるすべてのディレクトリに対して繰り返されることがわかります。 GNUで
$ v=foobar
$ find . -mindepth 1 -type d | xargs -n 1 -P 20 -i sh -c "v={}; echo $v"
foobar
foobar
foobar
foobar
foobar
foobar
foobar
foobar
foobar
foobar
foobar
...
あなたがどうなるパラレル:
find . -mindepth 1 -type d | parallel -P 20 'v={}; echo "$v"'
それは、コマンドラインではなく、sh' 'へxargsはの呼び出しによって展開されていますので、あなたの' $のv'がnullです。ドル記号が間違ったシェルによって解釈されないようにするには、一重引用符を使用します。異なる引用符がどのように機能するかについてのいくつかの洞察については、[この回答](http://stackoverflow.com/a/9712555/1072112)をチェックしてください。 – ghoti