4

sys.argv[1]とを再帰的に使用して、コマンドライン引数()glob.globのglobパターンに一致するファイルのリストを取得しようとしていますos.walk。問題は、bash(および他の多くのシェル)がglobパターンをファイル名に自動拡張することです。

grep -Rそれでは、標準のUNIXプログラム(例)はこれをどのように実行しますか?私はそれらがPythonにないことを知っていますが、これがシェルレベルで起こっているのであれば、それは問題ではありませんよね?スクリプトがグロブパターンを自動拡張しないようにシェルに指示する方法はありますか?グロブを無効にするように見えますがset -f、いわば、これを十分に早く実行する方法がわかりません。

PythonでGlob()を使用してファイルを再帰的に検索するのを見たことがありますか?、ただし、コマンドライン引数から実際にグロブパターンを取得する方法については説明していません。

ありがとう!

編集:

grepのようなperlスクリプトackは、引数の1つとしてperl正規表現を受け入れます。したがって、ack .*すべてのファイルのすべての行を印刷します。ただし.*、ディレクトリ内のすべての隠しファイルに展開する必要があります。スクリプトを読んでみましたが、perlがわかりません。どうすればこれを行うことができますか?

4

3 に答える 3

6

シェルは、コマンドの呼び出しを考える前にglob拡張を実行します。grepなどのプログラムは、グロブを防ぐために何もしません。できません。*これらのプログラムの呼び出し元であるあなたは、プログラムに、などの特殊文字を渡したいことをシェルに伝え、シェルに?それらを解釈させないようにする必要があります。あなたはそれらを引用符の中に入れることによってそれをします:

grep -E 'ba(na)* split' *.txt

( <something>と呼ばれるすべてのファイルで、などba splitを探します)この場合、一重引用符または二重引用符のいずれかでうまくいきます。一重引用符の間では、シェルは何も展開しません。二重引用符の間、、、およびは引き続き解釈されます。1つの文字の前に円記号を付けることで、シェルの拡張から1つの文字を保護することもできます。保護する必要があるのはワイルドカード文字だけではありません。たとえば、上記のパターンのスペースは引用符で囲まれているため、引数の区切り文字ではなく、引数の一部になります。上記のスニペットを作成する別の方法には、次のものがあります。bana split.txt$`\grep

grep -E "ba(na)* split" *.txt
grep -E ba\(na\)\*\ split *.txt

ほとんどのシェルでは、引数にワイルドカードが含まれているが、パターンがどのファイルとも一致しない場合、パターンは変更されずに、基になるコマンドに渡されます。したがって、次のようなコマンド

grep b[an]*a *.txt

システムに存在するファイルに応じて、異なる効果があります。現在のディレクトリに名前が。で始まるファイルが含まれていない場合、コマンドは名前が。と一致するファイルbのパターンを検索します。現在のディレクトリに、、、という名前のファイルが含まれている場合、コマンドはに展開されるため、2つのファイルとのパターンを検索します。言うまでもなく、スクリプトでこれに依存することはお勧めできません。コマンドラインでは、入力を節約できる場合がありますが、危険です。b[an]*a*.txtbaclavabnmhello.txtgrep baclava bnm hello.txtbaclavabnmhello.txt

ack .*ドットファイルを含まないディレクトリで実行すると、シェルが実行されack . ..ます。ackこのコマンドの動作は、 (現在のディレクトリの親)の下にあるすべてのファイルの空でない行(パターン:任意の1文字に一致)を再帰的に出力することです。現在のディレクトリとそのサブディレクトリ内のパターン(何にでも一致する)を検索する、とは対照的です( filename引数を渡さない場合の動作のため)。...ack '.*'.*ack

于 2011-05-24T10:08:09.813 に答える
1

grepに関しては、ファイル名のリストを受け入れるだけで、glob拡張自体は実行しません。パターンを引数として渡す必要がある場合は、コマンドラインで一重引用符で囲む必要があります。ただし、その前に、シェルに設計された仕事をさせることを検討してください。

于 2011-05-23T22:29:10.570 に答える
1

はい、set -fあなたは正しい方向に進んでいます。

シェルからPythonプログラムを呼び出すようです。

シェルを使用してコマンドを発行するときはいつでも、コマンド行をスキャンして、ワイルドカード、コマンド置換、およびその他の多くのものを処理しようとします。

したがって、コマンドラインでプログラムを実行する前に、グロビンをオフにする必要があります。

set -f
echo *
*

myprogram *.txt

文字列'*.txt'をプログラムに渡します。次に、内部グロブを使用してファイルを取得できます。

または、ラッパースクリプトを作成することで、基本的に同じことを行うことができます

 #!/bin/bash
 set -f
 myProgram ${@}

ここで、${@} are the arguments you pass in when you startmyProgram`は、コマンドライン、crontabから、または別のプロセスからexec(...)を介して実行されます。

これがお役に立てば幸いです。

于 2011-05-23T22:30:27.977 に答える