2017-02-13 13 views
1

これはすでに回答済みですが、適切な検索条件が見つからない場合は謝罪します。Bash:変数を介してコマンドに引数としてファイルパターンを渡します。

私はfindコマンドのために(ユーザー定義の設定に基づいて)動的に検索用語を定義しようとしている:私はコマンドをecho場合

# reading user settings results in array of filename patterns to delete: 
patterns=("*.url" "*.html") 
for i in ${patterns[@]}; do 
    find . -iname $i -delete 
done 

、結果の文字列は、例えば、正しく見えます

find . -iname "*.url" -delete 
find . -iname "*.html" -delete 

私には明らかなものがありませんが、何も試したことはありません。

私はBash 4.4.5を使用しています。

----------------チャールズ・ダフィーとL」にEDIT -----------------

私のおかげでL'lは正しい解決策です。配列の文字列と引用された変数を引用符で囲み、両方の変数を同時に引用することに失敗しました。

教訓:常にシェル変数を引用します。

+1

これはhttp://shellcheck.net/があなたを魅了する問題です。 –

+0

私はまだ自分自身の質問に答えるつもりはないが(誰かがより良い解答や説明を持っている場合に備えて)、解決策を見つけた。配列の二重引用符が問題であると思われます。配列の引用符を取り除き、var "" $ i "'をソフトクォートすると、期待どおりに動作します。引用符を含む文字列と私がまだgrokkingしていない引用された文字列の間には微妙な違いがあります。 –

+2

配列定義から引用符を削除するのは間違っています。これは、 'find'で評価されるのではなく、割り当て時にグロブが展開されるようにします。 –

答えて

4

The answer by l'L'lは良いものですが、渡されたすべてのパターンに一度だけfindを呼び出すことによってのは、それはもう少し効率的にしましょう単一のコマンドライン:

patterns=("*.url" "*.html") 
find_pat=() 

for i in "${patterns[@]}"; do 
    find_pat+=(-o -name "$i") 
done 

find . -iname '(' "${find_pat[@]:1}" ')' -delete 

実行すると、これが起動します:

find . -iname '(' -name '*.url' -o -name '*.html' ')' -delete 

... と一致するすべてのファイルを削除します。*.urlまたは*.htmlのいずれかを一度に削除します。


注:

  • 我々は常にで私たちのグロブを引用している:彼らは、割り当てに引用されている(アレイの拡張で、(私たちはpatterns配列へのグロブそのものを割り当てます)その結果ではなくglob自体を繰り返します)、そしてfindコマンドへの展開(したがって、その構文を拡張した結果ではなく、findのリテラルパターン構文を渡します)。
  • find_patの配列には-oが前に付いていますが、2番目の要素(配列は0でインデックス付けされています)から拡張されているため、その最初の文字はスキップされます-o。ここで使用される構文はparameter expansionです。
+0

すべての情報をお寄せいただき、ありがとうございます。私は基本的なフォームが機能した後に連結パターンを構築する予定でしたが、引用された配列文字列と引用された変数を頭で囲むのは難しいことでした。それは問題を "解決"するために様々な並べ替えを試みる私の尾を追いかけている。お待ち頂きまして、ありがとうございます。 –

+1

喜んで助けてください。実行モデルを理解するのが難しい、かつ重要である - あなたの検索するにはあなたにいくつかのキーワードを与える必要があり、非常に高レベルの概要を与えるために、引用符で囲まれていない拡張は、引用符などではない*他の解析段階の文字列分割を受け、グロブ(しかし*その変数に格納されている任意のコマンドを実行する '$ cmd'を安全に実行することはできません - その時点で[BashFAQ#50](http://mywiki.wooledge.org/BashFAQ/050)を参照してください) 。 [BashParser](http://mywiki.wooledge.org/BashParser)とそのさまざまなリンクから始めましょう。 –

3

はあなたの変数を二重引用符する必要があります。

for i in "${patterns[@]}"; do 
    find . -iname "$i" -delete 
... 

これはグロブと単語の分割防ぐことができます。あなたはいつものようにもエラーhttps://www.shellcheck.net/でスクリプトを確認することができます

...

+0

解決に感謝します。以前のテストでは、配列変数とループ変数の両方を同時に引用するのに失敗しました。どの[https://www.shellcheck.net/](https://www.shellcheck.net/)が指摘したか。 –

関連する問題