Bash機能で引用符を正しく使用する方法は?

Bash機能で引用符を正しく使用する方法は?

.bashrc私のファイルで次のbash関数を定義しようとしています。

function myfind() {
    find $1 -not -path venv -not -path .tox -name "$2" | xargs grep -n "$3"
}

これは私の期待には及ばなかった。この機能を使用してファイルからテキストを検索する場合、たとえば

myfind . *.py test

何も返しません。しかし、表現を直接使うとき

find . -not -path venv -not -path .tox -name "*.py" | xargs grep -n "test"

いくつかの一致を返します。

私は次の二重引用符を使ってみました。

function myfind() {
    find $1 -not -path venv -not -path .tox -name '"$2"' | xargs grep -n '"$3"'
}

または

function myfind() {
    find $1 -not -path venv -not -path .tox -name "'$2'" | xargs grep -n "'$3'"
}

これらの引用符を避けるようにしてください

function myfind() {
    find $1 -not -path venv -not -path .tox -name \"$2\" | xargs grep -n \"$3\"
}

しかし、これらのどれも機能しないようです。

このbash関数がパラメータの周りに引用符を「使用」するように変更するにはどうすればよいですか?

ベストアンサー1

ティーチーム:

myfind() {
  find "$1" '(' -name venv -o -name .tox ')' -prune -o \
            -name "$2" -type f -exec grep -Hne "$3" -- {} +
}

それから:

myfind . '*.py' test

また、見ることができます検索結果を繰り返すのはなぜ悪い習慣ですか?そのような出力を呼び出すのはなぜxargs間違っているのですか?find

あなたのアプローチにはいくつかの他の問題があります。

  • -path venv-path検討中のファイルのフルパスに一致するエントリはなく、呼び出しの最上位レベルでのみ一致します<contents-of-$1>/subdir/filemyfind venv ...私はあなたがというディレクトリに保存されているファイルを無視したいと思いますvenv。これは可能ですが、! -path '*/venv/*'後でディレクトリ内のすべてのファイルをフィルタリングするよりも、最初からそのディレクトリに入らないように指示する方が効率的です。 (ファイルパスがロケールで有効なテキストではない場合でも問題が発生する可能性があります。)find! -path '*/venv/*'

  • for 、あなたはの2番目から2番目の引数を形成するために、現在のディレクトリから一致するファイルのリストに拡張myfind first *.py lastするようにシェルに要求しています。これはforに渡してafterに渡したいリテラル引数です。したがって、以下が必要です。シェルが文字をワイルドカードとして解釈しないように文字を引用してください。ここでは、残りの3文字(、および)がシェルに特別ではないため、内容全体をwhileまたはで引用するだけで十分です。*.pymyfind*.pymyfindmyfindfind-name**.py'*.py''*'.py\*.py.py

    bashの代わりにzshを使用している場合は、.NETalias myfind='noglob myfind'でこれを行うことができます。これにより、シェルなしで拡張myfindできます。myfind . *.py test*.py

  • "$1"分割+glob(、でない)を防ぐには、パラメータ拡張を引用する必要があります$1

  • -HGNU 拡張子がない場合、findファイルが 1 つだけ見つかった場合、そのパスgrepは印刷されないため、一致する場所がわかりません。grepサポートされていない実装の場合は、追加の引数として渡すことができます-H/dev/null-exec grep -ne "$3" -- /dev/null {} +

  • !非標準に対応する標準(およびより短い)項目を参照してください-not

  • withで始まるgrep -n "$3"と、オプションとして扱われます。したがって、オプションに引数としてコンテンツを渡します。同じ問題がありますが、残念ながら標準的なソリューションはありません。ブロックされたコンテンツが考慮されます。$3-grep-e "$3"$3-efind "$1"find -- "$1"$1オプションfindそれで始まります-が、まだ次のように処理されます。スルブ、だから言うことはできません。たとえば、!というディレクトリ(も問題になる可能性があります。 BSDはfindこれをサポートしますが、GNUと他のほとんどの実装はそうではありません。ダッシュで始まるディレクトリを渡すために使用されます。find -f "$1"findfindmyfind ./-dir-starting-with-data- '*.py' pattern

  • shコード内の唯一の非標準構文はfunction name()関数定義構文です。 ksh 構文はfunction name {...;}、Bourne で標準bash構文はですname() {...;}bash時々サポートされることもありますが、function name() { ...; }それを使用する理由はありません。

  • -type f考慮事項のみを追加しました定期的なこれは、デバイスファイルやfifo内で検索を開始したくないので、ディレクトリやgrep ソケットに関するエラーが報告されるためです。 GNUを使用すると、findこれを置き換えて-xtype f最終的に一般的なファイルとして解決されるシンボリックリンクも考慮できます。

おすすめ記事