私は60 GBのメールを送信したメールアカウントを持っていますが、現在、昨年(2011年)のメールをアーカイブするためにメールクライアントを使用するのに苦労しています。
ターミナル経由で、2011-01-01から2011-12-31までのファイルを見つけるためにfindを使用しようとしていますが、役に立ちません。
2つの日付の間のファイルを見つけるにはどうすればよいですか?
関連する場合、最終目標は、検出された各ファイルを日付間隔に一致するフォルダーに移動するバッチになります。
私は60 GBのメールを送信したメールアカウントを持っていますが、現在、昨年(2011年)のメールをアーカイブするためにメールクライアントを使用するのに苦労しています。
ターミナル経由で、2011-01-01から2011-12-31までのファイルを見つけるためにfindを使用しようとしていますが、役に立ちません。
2つの日付の間のファイルを見つけるにはどうすればよいですか?
関連する場合、最終目標は、検出された各ファイルを日付間隔に一致するフォルダーに移動するバッチになります。
回答:
次のスクリプトを使用できます。
#!/bin/bash
for i in $(find Your_Mail_Dir/ -newermt "2011-01-01" ! -newermt "2011-12-31"); do
mv $i /moved_emails_dir/
done
findシェルforループで処理しないでください。-exec、-execdir、または-print0 | xargs通常代わりに使用されるべきです。通常はあまり望ましくないが、forループの使用を許可する別の可能な解決策はIFS、スペースがフィールド区切り文字として認識されないように一時的に設定することです。
findとexec?スペースの使用に対処する回答を追加してもよろしいですか?とても有難い。
Bashは2つの日付の間にファイルを見つけます:
find . -type f -newermt 2010-10-07 ! -newermt 2014-10-08
2010-10-07以降および2014-10-08以前のタイムスタンプを持つファイルのリストを返します
Bashは15分前から現在までのファイルを検索します。
find . -type f -mmin -15
15分前から現在までのタイムスタンプを持つファイルのリストを返します。
Bashは2つのタイムスタンプ間のファイルを検索します。
find . -type f -newermt "2014-10-08 10:17:00" ! -newermt "2014-10-08 10:53:00"
間のタイムスタンプのファイルを返します2014-10-08 10:17:00し、2014-10-08 10:53:00
以下のようSubv3rsionさんとエリックLeschinskiの答えが表示され、-newermt述語選択したファイルは、そのオペランドとして指定した日付(およびオプションの時間)よりも多く、最近変更しました。ファイルを見つけるには
srcdir(つまり、そのサブディレクトリ、サブディレクトリなどを含む)destdir...実行できます:
find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -i {} destdir/ \;
で-exec表現、検索の代わりに見つかったファイル名を渡します{}。;とが意味する-execコマンドが実行されるようにすることを、その引数は、すべての(場合には、その後の表現は、その特定した後に見つけることが渡され提供されている-exec-この例については以下を参照の述語の引数)。シェルによって特別に解釈されないように;エスケープする必要があります\;。(を指定しないと\、コマンド;全体が終了findし、改行と同じように機能します。このfindコマンドの後にこの-exec式がない;場合でも、引数を渡さないと構文エラーになります。)
ファイルを一覧表示するだけの場合(古い電子メールがどのように保存されているか、または他のどのファイルが存在するかわからない場合はお勧め-execします)、その右側のすべてを省略します。(電子メールの場合、多くの場合、異なる日付からの電子メールは同じファイルに保存されます。ここでの質問で説明されている状況では、ファイルを移動する前に保存方法を調査することをお勧めします。)それらの-print前に追加し-execます。
mv -i 次の場合に発生するように、ファイルが宛先で上書きされるたびにプロンプトが表示されます。
srcdir同じfind操作中に既に移動されている、またはsrcdir、同じfind操作中にどこかに作成されましたfind。rm:重複した名前のファイルを処理する方法には、他のオプションがあります。
-i(つまり)では、通常、承認を求めるプロンプトは表示されませんが、宛先ファイルが読み取り専用の場合は承認を求めます。(読み取り専用ファイルを実行しているユーザーがファイルを所有している場合など、場合によっては上書きすることもできます。)mv {} destdir/mvmvmv同じ名前のファイルを常に上書き(試行)したい場合は、を使用しますmv -f。mv -n。mv-bおよび--backupフラグを受け入れて、宛先にすでに存在する同じ名前のファイルの名前を自動的に変更します。デフォルトで~は、バックアップ名を生成するために追加され、名前を持つファイルとバックアップ名を持つファイルが宛先に既に存在する場合、バックアップファイルは上書きされます。このデフォルトは、起動時に渡されるオプションmvと環境変数によってオーバーライドできます。詳細man mvおよび以下の例を参照してください。すべてのファイルを移動するには、~サフィックスを使用して重複する名前のファイルをバックアップし、ファイルが既に存在する場合は番号付きのサフィックスを使用します(何も上書きしないようにするため)。.~n~.~
find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv --backup=existing {} destdir/ \;
mv -n同じ名前の別のファイルがあったために移動されなかったファイルを使用して知りたい場合、おそらく最良の方法は、元のfindコマンド-execをその右側にすべてなしで再度実行することです。これにより、名前が印刷されます。
また、元のfind .... -exec ...コマンドを実行した後に作成された一致するファイルの名前も出力しますが、このアプリケーションでは、古い変更時刻のファイルを探しているため、通常は存在しません。ファイルに実際の年齢よりも古い変更タイムスタンプを与えることは可能ですが、touch他のメカニズムもありますが、この場合、あなたの知らないうちにそれは起こりそうにないでしょう。
mv -nファイルの移動を控えた場合、レポートも特別な終了コードも返しません。そのfindため、実行中にスキップされたファイルをすぐに通知する場合は、そのための別の手順を実行する必要があります。1つの方法は次のとおりです。
find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -n {} destdir/ \; \
-exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \;
おそらくいくつかのマイナーな技術的考慮事項:これmvは、宛先に存在するのとは異なる理由でファイルのコピーに失敗した場合に誤って警告し、成功を報告して終了します。それはありそうにないが、私はそれが不可能だと確信していない。また、潜在的に競合状態に陥ります。実際のエラーがまったくない場合、古いファイルが移動されてからチェックするまでの非常に短い時間に同じ場所に同じ名前の新しいファイルが作成された場合に警告します削除されたかどうかを確認します。(アプリケーションを考えると、私はどちらかの問題がこれまで実際に起こることはないだろう。)リンク先を確認書き換えることができ前に後ではなくファイルを移動すると、競合状態はソースファイルではなく、新しく作成された宛先ファイルに関連します。また、findまたはmv(または[、あるべきではない)によって報告されるエラーと警告は標準エラーに書き込まれますが、...skipped (exists in...警告は標準出力に書き込まれます。通常、両方が端末に表示されますが、スクリプトを作成している場合はこれが問題になることがあります。
読みやすくするために、このコマンドを2行に分割しました。そのように実行することも\、改行と改行(つまり、改行)を削除することもできます。
findコマンドはどのように機能しますか?find述語は、戻り値に使用されるテスト(-typeandなど-newermt)、または副作用(副作用)によく使用されるアクション(-printandなど-exec)になります。
式の間に演算子(-afor や、-ofor や)が指定されていない場合-aは、暗示されます。andおよびorに対して短絡評価をfind採用しています。(つまり、)は、p式とq式の両方が真である場合にのみ真であるため、pが偽の場合、qを評価する必要はありません。私たちはこれらの用語でそれをしばしば考えませんが、これは評価されるべき後続のアクションまたはテストに対してテストが真実でなければならない理由です。たとえば、ディレクトリにアクセスするとします。false と評価されるため、その後すべてをスキップできます。p qp -a qfind-type f
テストと同様に、アクションもtrueまたはfalseに評価されます。この方法で-exec、実行されたコマンドが成功(true)または失敗(false)のいずれであるかを報告します。この一連の-exec式は、暗黙的なandに接続されています:
-exec mv -n {} destdir/ \; -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \;
これはファイルを移動しようとし、mv失敗が報告された場合は停止します。他の問題が原因で移動されなかった場合、正しくスキップされたファイルについて警告したくありません。
しかし、成功した場合は、[コマンドを実行します。のようにfind、[引数として渡される独自の種類の式をサポートします。(の代わりに渡された)[ -f {} ]後のオペランドが存在する(通常のファイルである)かどうかをチェックし、true / successまたはfalse / failureを返します。(多くのコマンドの終了ステータスは成功または失敗を示すものとして最も適切に解釈されますが、通常、存在ステータスは真または偽として最も適切に解釈されます。)-ffind{}
[
[falseが返された場合、ファイルはなくなっているため移動されたため、何もする必要はありません。ただし、[falseが返された場合、ファイルはまだ存在しています。次に、警告メッセージを出力findする次の-exec式を評価します。
man findおよびGNU Findutilsリファレンスマニュアルman mvおよびGNU Coreutilsリファレンスマニュアル(特に11.4 mv:ファイルの移動(名前変更))man \[および16.3テスト:ファイルの種類を確認し、Coreutilsドキュメントの値を比較します。シェルの組み込みではなく/usr/bin/[)を使用すると実行されます。[find-exec [-exec ... +てmv -t、いつかすぐに、。