.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/file
。myfind venv ...
私はあなたがというディレクトリに保存されているファイルを無視したいと思いますvenv
。これは可能ですが、! -path '*/venv/*'
後でディレクトリ内のすべてのファイルをフィルタリングするよりも、最初からそのディレクトリに入らないように指示する方が効率的です。 (ファイルパスがロケールで有効なテキストではない場合でも問題が発生する可能性があります。)find
! -path '*/venv/*'
for 、あなたはの2番目から2番目の引数を形成するために、現在のディレクトリから一致するファイルのリストに拡張
myfind first *.py last
するようにシェルに要求しています。これはforに渡してafterに渡したいリテラル引数です。したがって、以下が必要です。シェルが文字をワイルドカードとして解釈しないように文字を引用してください。ここでは、残りの3文字(、および)がシェルに特別ではないため、内容全体をwhileまたはで引用するだけで十分です。*.py
myfind
*.py
myfind
myfind
find
-name
*
*.py
'*.py'
'*'.py
\*.py
.
p
y
bashの代わりにzshを使用している場合は、.NET
alias myfind='noglob myfind'
でこれを行うことができます。これにより、シェルなしで拡張myfind
できます。myfind . *.py test
*.py
"$1"
分割+glob(、でない)を防ぐには、パラメータ拡張を引用する必要があります$1
。-H
GNU 拡張子がない場合、find
ファイルが 1 つだけ見つかった場合、そのパスgrep
は印刷されないため、一致する場所がわかりません。grep
サポートされていない実装の場合は、追加の引数として渡すことができます-H
。/dev/null
-exec grep -ne "$3" -- /dev/null {} +
!
非標準に対応する標準(およびより短い)項目を参照してください-not
。withで始まる
grep -n "$3"
と、オプションとして扱われます。したがって、オプションに引数としてコンテンツを渡します。同じ問題がありますが、残念ながら標準的なソリューションはありません。ブロックされたコンテンツが考慮されます。$3
-
grep
-e "$3"
$3
-e
find "$1"
find -- "$1"
$1
オプションfind
それで始まります-
が、まだ次のように処理されます。スルブ、だから言うことはできません。たとえば、!
というディレクトリ(
も問題になる可能性があります。 BSDはfind
これをサポートしますが、GNUと他のほとんどの実装はそうではありません。ダッシュで始まるディレクトリを渡すために使用されます。find -f "$1"
find
find
myfind ./-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
最終的に一般的なファイルとして解決されるシンボリックリンクも考慮できます。