2017-11-12 8 views
0

私は以下の問題があります:スペースでファイル名を扱うときに "" {} ""をxargsに渡す必要はありませんか?

ファイルを見つけるためにxargs-find構造を使いたいと思います。 違いは、私がでのCommand1としてではなくcommand2のよう見つける使用しないことを、次のとおりです。

command1 | xargs command2 

ファイル名は、例えば自分の名前

にスペースを持っている場合、問題が発生します。

私が試している場合:

echo 01.Here Comes The Night Time II.flac | xargs -pi find ~/Multimedia/Musik/flac/ -name "\""{}"\"" 

find ~/Multimedia/Musik/flac/ -name "01.Here Comes The Night Time II.flac" ?...yes 

何も見つかりません。 xargsの-0オプションでも動作しません。

私はコピーして、xargsコマンドからのインタラクティブな印刷要求を貼り付ける場合は、ファイルが見つかります。

find ~/Multimedia/Musik/flac/ -name "01.Here Comes The Night Time II.flac" 

~/Multimedia/Musik/flac/Arcade Fire/Reflektor (CD 2)/01.Here Comes The Night Time II.flac 

は間違って何かが、私はパイプを「フィード」のように、あるいは私には、道にあります「(私は試行錯誤によって考え出し)findコマンドで、または他の何か?

+1

'... -name {}'はどうなりますか? – melpomene

+1

"xargs -pi find〜/ Multimedia/Musik/flac/-name {}"(-0オプションなし)コマンドを実行すると、これは私が試していない唯一の組み合わせであったようです。しかし、なぜ今働いていますか?これによりxargsのコマンド要求が出てきます。 "find〜/ Multimedia/Musik/flac/-name 01.Here Comes The Night Time II.flac"となり、この "コピー&ペースト"は機能しません。 – madZeo

+0

重い手紙の編集を許しますが、これは同じ質問を他の人に向けた最初のアプローチです(また、質問されている内容に正確に答えることに興味がある人には明らかになります)。 –

答えて

2

あなたがプログラムを内部的に開始されている方法とどのようにコマンドがシェルによって解釈されますについて混乱しているようだ。

でunix、プログラムを開始するには3つのパラメタrs:

  1. ファイル名。これは、実行するプログラムへのパスを含む文字列です。
  2. 文字列のリスト。規約では、これらの「コマンドライン引数」を呼び出します。
  3. 文字列の別のリスト。大会ではこれらを「環境」と呼んでいますが、OSレベルではもう一つの文字列リストです。しかし、すべてのプログラム/ライブラリは、これをユーザとアプリケーションプログラマの両方に隠すために共謀しています。

あなたがシェルにコマンドを入力すると、多くのことが起こるが、最も簡単な場合には、それはスペースで区切られた単語のちょうど束だ:

$ foo bar baz 

$は、シェルプロンプトではなく、何かを表し、あなたが入力します。)シェルは3つのワード(foobarbaz)にこの行を分割し、プログラムの名前として最初のものを解釈

PATH Vに記載されているディレクトリで検索しますariable)。 PATHリストを/usr/binとし、実際には/usr/bin/fooプログラムがあるとしましょう。

今シェルは次のようにプログラムを開始する(擬似コード):

exec("/usr/bin/foo", ["foo", "bar", "baz"], [...]) 

すなわち/usr/bin/fooで実行可能ファイルを実行し、引数として3つの文字列のリストを渡します。 ([...]はこれから無視する環境を表しています。)

代わりにこれを行うとどうなりますか?

$ foo "bar baz" 

引用符は、シェルが行を単語に分割する方法に影響します。特に、引用符で囲まれた" "(スペース)は区切り文字としては機能しませんが、文字通り取られます。これにより、2要素のリスト(foobar baz)が得られます。引用符は単語そのものではないことに注意してください。

内部的にはこれは、次の呼び出しに変換します。

exec("/usr/bin/foo", ["foo", "bar baz"], [...]) 

は再び、第二引数は、単純にスペースが含まれています。埋め込み引用符はありません。

だから何が

$ xargs -pi find ~/Multimedia/Musik/flac/ -name "\""{}"\"" 

のようなコマンドでどうなりますか?

これは、シェルによって単語のリストに解析されます。 ~は、ホームディレクトリの名前に置き換えられます。 "\""は、\"または'"'(すなわち、リテラル"文字)を書く複雑な方法です。最終的なリストはxargs,-pi,find,/home/madZeo/Multimedia/Musik/flac/,-name,"{}"です。最後の引数は4文字の文字列"{}"がいかに

exec("/usr/bin/xargs", ["xargs", "-pi", "find", "/home/madZeo/Multimedia/Musik/flac/", "-name", "\"{}\""], [...]) 

注:これは、次の呼び出しに変換します。

xargsは、その最初の引数(-pi)をオプション指定として扱います。特に、-iは、引数リスト内の{}を標準入力から読み取られた現在の値で置き換えるよう指示します。

xargs標準入力から(echoパイプのため)01.Here Comes The Night Time II.flacという行が読み込まれます。

これは、リストfind/home/madZeo/Multimedia/Musik/flac/-name"01.Here Comes The Night Time II.flac"を得{}の代わりに中に置換されます。 xargsは、このようなfindを起動します:

exec("/usr/bin/find", ["find", "/home/madZeo/Multimedia/Musik/flac/", "-name", "\"01.Here Comes The Night Time II.flac\""], [...]) 

これは、名前が文字通り"(引用符)で始まるファイルを検索するfindに指示します。そのようなファイルは存在しないので、これは失敗します。


修正は、このようなコマンドを書くことである:

$ xargs -pi find ~/Multimedia/Musik/flac/ -name {} 

これは最終的に何をしたいである、

exec("/usr/bin/find", ["find", "/home/madZeo/Multimedia/Musik/flac/", "-name", "01.Here Comes The Night Time II.flac"], [...]) 

を実行して終了します。

xargsは、サブコマンド(この場合はfind)を直接実行するという問題があります。シェルによって再解析される新しいコマンドラインは構築されません。それは入力引数をスペースで分割しません。引用符は解釈しません。$または*または\のような特殊文字は気にしません。与えられた単語のリストを取り、サブ文字列{}を現行の入力で置き換えて実行します。

この最終コマンドを慎重に受け取り、シェルに貼り付けると、言葉の分割、引用の削除などが行われ、異なる結果につながります。

関連する問題