Maildir ディレクトリの Bash スクリプト

Maildir ディレクトリの Bash スクリプト

Maildirディレクトリに500個のファイルをgrepしたいと思います。私は命令を出す。

grep MyPattern *

エラーメッセージが表示されます。

bash: /usr/bin/grep: Argument list too long

そのため、ファイルのリストをMyFilesファイルに保存し、次のコマンドを実行します。

for i in $(`cat MyFiles`); do echo $i; done

grepを実行する前にエコーを実行して確認したいと思います。ただし、これにより次のエラーが発生します。

bash: 1434361691.M617282P6399V0000000000000808I00000000000E16C1_23.ananda-linux,S=10055:2,S: command not found

ここで、1434...はディレクトリの最初のファイルです。

では元の質問に戻ります。メールボックス内のこれらすべてのファイルを見つけるためにgrepする方法。 50,000以上の電子メールを含むより大きなメールボックスがあります。

答え1

grep現在のディレクトリで繰り返しファイルリストを整理してみてください。

grep -r MyPattern .

これはサブディレクトリから検索するため、まったく同じではありませんが、*メールディレクトリの場合は通常必要なものです。

答え2

シェルが外部コマンドを実行するとき、コマンドラインはファイル名ワイルドカードパターン(たとえば)を拡張した後に特定の長さを*超えてはいけません。

あなたの場合、grep 'PATTERN' *拡張はシェルが実行するには長すぎるコマンドです。

2番目の例では:

for i in $(`cat MyFiles`); do echo $i; done

に保存されているファイル名を繰り返しようとしましたが、MyFiles構文が非常に間違っています。

$(`cat MyFiles`)

同じですか?

$( $(cat MyFiles) )

これは、内容がMyFilesコマンドとして解釈されることを意味します。これがcommand not foundエラーが発生する理由です。

この問題を解決する方法はさまざまですが、ファイルの内容を繰り返すのは良いアプローチではありません。

Stephenは素晴らしいソリューションを提供しました。彼の答えに、もう1つは、現在の作業ディレクトリがMaildirフォルダであると仮定することです。

find . -type f -exec grep 'PATTERN' {} +

これは、grep大規模ファイルの配置に対して複数回実行されます。できるだけ

これは次のようになります。

printf '%s\n' * | xargs grep 'PATTERN'

ただし、このfindコマンドはスペースと改行を含むファイル名を処理します。

ここのコマンドは、printf1行に1つのファイル名を出力します。grep 'PATTERN' *ほとんどの場合と同じ問題は発生しません。組み込みコマンドなので、シェルから外部コマンドとして実行する必要はありません。

catループソリューションも機能しますが、ループ出力の代わりに単に次のことができます。

for name in *; do
    grep 'PATTERN' "$name"
done

これは次のように仮定します。一般ファイルのみ現在のディレクトリにあります。

メールメッセージのみを処理するには、次のものを使用できます。

for name in *,*; do
    grep 'PATTERN' "$name" /dev/null
done

これは、1つ以上のカンマを含む名前を繰り返します。また、指定されたパターンに一致するファイル名を/dev/null強制的に出力するように追加しました。grepサポートしている場合は、代わりに/dev/null削除して使用できます-Hgrepgrep

これらのループは、grepディレクトリ内の各ファイルに対して一度だけ実行されるため、遅くなります。

関連情報