
つまり、コマンドによってリストされたディレクトリをコマンド内で使用したいのですfind
。
find $(produces_dir_names --options...) -find-options...
問題はディレクトリ名に空白があることです。生成コマンドの出力で空白を引用符で囲めば十分だと思いました (これは変更できます)。
"a" "a b" "a b c"
しかし、bash は次のように文句を言います:
find: ‘"a"’: No such file or directory
find: ‘"a’: No such file or directory
find: ‘b"’: No such file or directory
find: ‘"a’: No such file or directory
find: ‘b’: No such file or directory
find: ‘c"’: No such file or directory
ご覧のとおり、see はbash
引用符があっても、コマンドの出力をスペースで分割します。 をいじって に設定しようとしましたIFS
が\n
、理解が不十分でうまく動作しないようです。
私が見つけた唯一の回避策は、この Stack Overflow の質問にありました:
bash コマンド置換引用符の削除つまり、eval
その前に を置くのですが、これはちょっと見苦しいようです。
私の質問:
簡単な方法はありますか? また、 を使用せずにこの置換を記述するとどのようになりますかeval
?
引用符は本当に必要ですか?
例(同じ出力を生成):
find $(echo '"a" "a b" "a b c"')
答え1
たぶん2行で
IFS=$'\n' DIRS=( $(produces_dir_names --options...) )
find "${DIRS[@]}" -find-options...
例:
$ mkdir -p "/tmp/test/a b/foo" "/tmp/test/x y/bar"
$ IFS=$'\n' DIRS=( $(printf "/tmp/test/a b\n/tmp/test/x y\n") )
$ find "${DIRS[@]}" -mindepth 1
/tmp/test/a b/foo
/tmp/test/x y/bar
しかし、一般的にこれは良いスタイルではありません。たとえば、DIRS に改行が含まれている場合は問題が発生します。null バイトで終了する文字列を出力するように "produces_dir_names" を修正した方がよいでしょう。私の例では、次のようになります。
$ printf "/tmp/test/a b\0/tmp/test/x y\0" | xargs -0 -I '{}' find '{}' -mindepth 1
/tmp/test/a b/foo
/tmp/test/x y/bar
「produces_dir_names」を修正できない場合、私の最後のコメントに関して、最も一般的な解決策は次のようになります。
produces_dir_names --options... | tr '\n' '\0' | xargs -0 -I '{}' find '{}' -find-options...
回避するために「produces_dir_names」を修正しない限り、「改行」の問題は依然として残りますtr
。
答え2
rudimeier の回答produces_dir_names
は良いです — 特に、ヌル終端文字列を印刷するように変更する部分— しかし、彼の回答からはfind
、ディレクトリごとに1回実行されることは明らかではないかもしれません。これが十分であれば、それで結構です。しかし、もちろん、find
複数の開始点で呼び出すことも可能です。たとえば、
探す ディレクトリ1ディレクトリ2ディレクトリ3 -検索オプション...
質問から、それがあなたが望んでいることであることがわかります。これは次のように実行できます。
printf "a\0a b\0a b c" | xargs -0 sh -c '"$@" を検索 -検索オプション...' シュ
これにより、コマンドにすべてのディレクトリ名が追加された状態で が 1 回xargs
呼び出されます。その後、シェルはそれらのディレクトリ名のリストを展開します。sh -c
"$@"
PS produces_dir_names
1 つのコマンド ラインに入力するにはディレクトリ名が多すぎる場合は、xargs
強制的にいくつかのコマンドが生成されます。生成されているxargs --verbose
コマンドを確認するには、を使用しますxargs
。
答え3
表示されるエラー メッセージの謎を解くために:
find: ‘"a"’: No such file or directory find: ‘"a’: No such file or directory find: ‘b"’: No such file or directory find: ‘"a’: No such file or directory find: ‘b’: No such file or directory find: ‘c"’: No such file or directory
答えはBashの引用符削除では、結果としてコマンド置換から。
からLESS='+/^ *Quote Removal' man bash
Quote Removal After the preceding expansions, all unquoted occurrences of the charac- ters \, ', and " that did not result from one of the above expansions are removed.
参照される「以前の拡張」には次のものが含まれます。
EXPANSION Brace Expansion Tilde Expansion Parameter Expansion Command Substitution Arithmetic Expansion Process Substitution Word Splitting Pathname Expansion Quote Removal