3

次のコマンドを使用して、現在のディレクトリ内およびその下にあるすべてのPythonソースファイルの文字列をgrepします。

find . -name '*.py' -exec grep -nHr <string> {} \;

単純化して、次のように入力できるようにします

findpy <string>

そして、まったく同じ結果が得られます。エイリアスは文字列展開のみを行うため、十分ではないようです。指定する必要のある引数は最後の引数ではありません。関数がタスクに適しているように思われるので、いくつか質問があります。

  • どうやって書くの?
  • どこに置けばいいの?
4

9 に答える 9

10

このためのスクリプト全体を作成したくない場合は、シェル関数だけで作成できます。

findpy() { find . -name '*.py' -exec grep -nHr "$1" {} \; ; }

...しかし、それを ~/.bashrc と ~/.bash_profile の両方で定義する必要がある場合があるため、ログイン シェルとインタラクティブ シェルの両方に対して定義されます (bash のマニュアル ページの INVOCATION セクションを参照してください)。

于 2009-05-29T05:30:23.737 に答える
6

補足として、何をしているのかについてAckを確認する必要があります。Perl で書かれた Grep の代替として設計されています。ターゲット言語に基づいてファイルをフィルタリングするか、.svn ディレクトリなどを無視します。

例 (Trac ソースからのスニペット):

$ ack --python foo ./mysource
ticket/tests/wikisyntax.py
139:milestone:foo
144:<a class="missing milestone" href="/milestone/foo" rel="nofollow">milestone:foo</a>

ticket/tests/conversion.py
34:        ticket['foo'] = 'This is a custom field'

ticket/query.py
239:        count_sql = 'SELECT COUNT(*) FROM (' + sql + ') AS foo'
于 2009-05-29T18:19:44.873 に答える
6

上記のすべての「find ... -exec」ソリューションは、機能するという意味では問題ありませんが、非常に非効率的であり、大きなツリーでは非常に遅くなります。その理由は、*.py ファイルごとに新しいプロセスを起動するためです。代わりに、xargs(1) を使用し、(ディレクトリではなく) ファイルに対してのみ grep を実行します。

#! /bin/sh
探す 。-name \*.py -type f | xargs grep -nHr "$1"

例えば:

$ time sh -c 'find . -name \*.cpp -type f -exec grep foo {} \; >/dev/null'
実質 0m3.747s
$ time sh -c 'find . -name \*.cpp -type f | xargs grep foo >/dev/null'
実質 0m0.278s
于 2009-05-29T05:46:33.330 に答える
2

私は似たようなものが欲しかったのですが、Idelic の答えは、 の優れた機能の 1 つを思い出させてくれましxargsた。つまり、コマンドを最後に置くということです。ほら、私の問題は、「パラメーターを受け入れる」シェルエイリアスを書きたかったことでした(実際には、パラメーター so を渡すことができるように展開しますgrep)。

に追加したものは次のbash_aliasesとおりです。

alias findpy="find . -type f -name '*.py' | xargs grep"

このように、findpy WORDor findpy -e REGEXor findpy -il WORD- と書くことができます。ポイントは、任意のgrepコマンド ライン オプションを使用できるということです。

于 2013-06-13T05:38:34.773 に答える
1

次の3行をという名前のファイルに入れますfindpy

#!/bin/bash

find . -name '*.py' -exec grep -nHr $1 {} \;

次に言う

chmod u+x findpy

私は通常、binこのような小さなシェルスクリプトを配置するホームディレクトリに呼び出されるディレクトリを持っています。必ずディレクトリをに追加してくださいPATH

于 2009-05-29T04:09:07.437 に答える
1

スクリプト:

#!/bin/bash
find . -name '*.py' -exec grep -nHr "$1" {} ';'

私がそれをする方法です。

あなたはそれをのようなエディタで書き、vimあなたの道のどこかにそれを置きます。私の通常のアプローチは、~/binディレクトリを作成し、.profileファイル(または同等のもの)に次のものが含まれていることを確認することです。

PATH=$PATH:~/bin
于 2009-05-29T04:12:45.523 に答える
1

次の行を ~/.bashrc または ~/.bash_profile または ~/.profile に追加します

alias findpy='find . -type f -name "*.py" -print0 | xargs -0 grep'

その後、このように使用できます

findpy def

またはgrepオプションを使用

findpy -i class

次のエイリアスは、git および svn のバージョン管理メタディレクトリを無視します。

alias findpy='find . -type f -not -path "*/.git/*" -a -not -path "*/.svn/*" -name "*.py" -print0 | xargs -0 grep'
于 2013-09-25T06:47:50.137 に答える
1

多くのバージョンの grep には、再帰を実行したり、ファイル名のパターンを指定したりするオプションがあります。

grep --perl-regexp --recursive --include='*.py' --regexp="$1" .

これは、現在のディレクトリ (.) から開始して再帰し、'py' で終わるファイルのみを調べ、Perl スタイルの正規表現を使用します。

お使いのバージョンの grep が --recursive と --include をサポートしていない場合でも、find と xargs を使用できますが、find に -print0 引数と --null オプションを使用して、スペースが埋め込まれたパス名を許可してください。それを処理するために xargs に。

find . -type f -name '*.py' -print0 | xargs --null grep "$1"

動作するはずです。

于 2009-05-30T00:06:30.773 に答える
0
#######################################################################################
#
# Function to search all files (including sub-directories) that match a given file
# extension ($2) looking for an indicated string ($1) - in a case insensitive manner.
#
# For Example:
#
# -> findfile AllowNegativePayments cpp
#
#
#######################################################################################
findfile ()
{
    find . -iname "*.$2*" -type f -print0 | xargs -0 grep -i "$1" {} \; 2> /dev/nul
}

alias _ff='findfile'
于 2013-07-22T01:52:13.140 に答える