web-dev-qa-db-ja.com

「検索」を使用して2つの日付の間のファイルを検索する方法?

私は60 GBのメールを送信したメールアカウントを持っていますが、現在、昨年(2011年)のメールをアーカイブするためにメールクライアントを使用するのに苦労しています。

ターミナル経由で find を使用して、2011-01-01と2011-12-31の間のファイルを検索しようとしていますが、使用できません。

2つの日付の間のファイルを見つけるにはどうすればよいですか?

関連する場合、最終目標は、検出された各ファイルを日付間隔に一致するフォルダーに移動するバッチです。

20
Zuul

次のスクリプトを使用できます。

#!/bin/bash
for i in $(find Your_Mail_Dir/ -newermt "2011-01-01" ! -newermt "2011-12-31"); do
  mv $i /moved_emails_dir/
done

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分前から現在までのタイムスタンプを持つファイルのリストを返します。

2つのタイムスタンプ間でファイルを検索する:

find . -type f -newermt "2014-10-08 10:17:00" ! -newermt "2014-10-08 10:53:00"

2014-10-08 10:17:002014-10-08 10:53:00の間のタイムスタンプを持つファイルを返します

39
Eric Leschinski

ファイルを移動し、重複する名前があるときにユーザーにプロンプ​​トを表示します。

Subv3rsion's および Eric Leschinski's の回答が示すように、-newermt述語は、オペランドとして指定された日付(およびオプションの時間)よりも最近変更されたファイルを選択します。ファイルを見つけるには

  • srcdirの任意の場所(つまり、サブディレクトリ、サブディレクトリなどを含む)
  • 最終変更日(たとえば)2014年9月
  • 、それらを移動destdir

...実行できます:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -i {} destdir/ \;

-exec式では、findは{}の代わりに見つかったファイル名を渡します。 ;は、実行するコマンドとその引数がすべて提供されたことを-execに示します(その特定の-exec述語の引数の後に検索するために後続の式が渡される場合-この例については以下を参照してください)。 ;は、\;としてエスケープする必要があるため、シェルによって特別に解釈されません。 (\がなければ、;findコマンド全体を終了し、改行と同じように機能します。このfindコマンドはこの-exec式の後には何もありませんが、;引数を渡さないと構文エラーになります。)

ファイルを一覧表示するだけの場合(古い電子メールがどのように保存されているか、または他にどのファイルが存在するかわからない場合はお勧めします)、-execおよびその右側のすべてを省略します。 (電子メールの場合、多くの場合、異なる日付の電子メールは same ファイルに保存されます。ここで質問に記載されている状況の場合、ファイルを移動する前に保存方法を調べることをお勧めします。 )それらの名前を印刷して移動したい場合は、-printの前に-execを追加します。

mv -iは、次の場合に発生するように、宛先でファイルが上書きされるたびにプロンプ​​トを出します。

  • 以前のバックアップから同じ名前のファイルが存在する、 or
  • 同じ名前であるがsrcdirの異なるサブディレクトリにあるファイルは、同じfind操作中に既に移動されています。 or
  • (最も可能性が低い)同じ名前のファイルが、同じsrcdir操作中に、元のファイルが移動された後すぐにfindのどこかに作成されたfindが別のサブディレクトリを横断すると、見つけるのに十分です。

rmを呼び出す他の方法:

重複した名前のファイルを処理する方法には他のオプションがあります。

  • -i(つまり、mv {} destdir/)がないと、mvは通常、承認を求めるプロンプトを表示しませんが、宛先ファイルが読み取り専用の場合はそうします。 (mvは、実行中のユーザーがファイルを所有している場合など、読み取り専用ファイルの上書きに成功することさえあります。)
  • その程度の対話性さえ必要とせず、mvに常に同じ名前のファイルを上書き(試行)させたい場合は、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を使用し、同じ名前の別のファイルがあったためにどのファイルが移動されなかったかを知りたい場合、おそらく、-execとその右側のすべてを使用せずに、元のfindコマンドを再度実行するのが最善の方法です。これにより、名前が印刷されます。
また、元のfind .... -exec ...コマンドを実行したために作成された一致するファイルの名前も出力しますが、このアプリケーションでは、変更時間が古いファイルを探しているため、通常は存在しません。 touchおよびその他のメカニズムを使用して、ファイルに実際の年齢よりも古い変更タイムスタンプを付けることは可能ですが、この場合、ユーザーの知らないうちに発生する可能性は低いようです。

名前が重複しているためにファイルがスキップされることをすぐに知る:

mv -nは、ファイルの移動を控えた場合、特別な exit code を報告せず、返しません。したがって、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が宛先に存在するのとは異なる理由でファイルのコピーに失敗し、終了 報告成功の場合に誤って警告します。それはありそうにないが、私はそれが不可能だと確信していない。また、潜在的に 競合状態 が発生します:古いファイルの後の非常に短い時間の間に同じ場所に同じ名前の新しいファイルが作成された場合、実際のエラーがまったくないときに警告します削除されたかどうかを確認する前に移動されました。 (アプリケーションを考慮すると、どちらの問題も実際に発生することはないでしょう。)ファイルの移動後 before をチェックするように書き換えることができます。その後、競合状態は新しくなります。ソースファイルの代わりに宛先ファイルを作成しました。そして、findまたはmv(または、[はないはずですが)によって報告されたエラーと警告は 標準エラー に書き込まれますが、...skipped (exists in...警告は 標準出力 に書き込まれます=。通常、両方が端末に表示されますが、スクリプトを作成している場合はこれが問題になることがあります。

読みやすくするために、このコマンドを2行に分割しました。そのように実行することも、\と改行(つまり、改行)を削除することもできます。

そのfindコマンドはどのように機能しますか?

find述語は、 tests -type-newermtなど)で戻り値に使用されるか、 actions -print-execなど) 頻繁にが副作用に使用されます。

演算子( and -a or -oなど)が式の間に指定されていない場合、-aが暗黙指定されます。 findは、 and および or に対して 短絡評価 を使用します。 pq(つまり、p -a q)は、 p q の両方の式が真である場合にのみ真になるため、 q p がfalseの場合、評価する必要はありません。私たちはこれらの用語でそれをしばしば考えませんが、これは評価されるべき後続のアクションまたはテストに対してテストが真実でなければならない理由です。たとえば、findがディレクトリに来たとします。 -type fをfalseに評価するため、その後すべてをスキップできます。

テストと同様に、アクションもtrueまたはfalseに評価されます。このようにして、-execは、実行されたコマンドが成功(true)または失敗(false)を報告して終了したかどうかを報告します。暗黙的な and に接続されたこの-exec式のチェーンがあります。

-exec mv -n {} destdir/ \; -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \;

これはファイルを移動しようとし、mvが失敗を報告した場合、停止します。他の問題が原因で移動されなかった場合、正しくスキップされたファイルについて警告したくありません。

しかし、成功した場合は [コマンド を実行します。 findと同様に、[は、引数として渡される独自の種類の式をサポートします。 [ -f {} ]は、-fの後のオペランド({}の代わりにfindによって渡される)が存在するかどうかを確認し(通常のファイル)、true/successまたはfalse/failureを返します。
(多くのコマンドの終了ステータスは、成功または失敗を示すものとして最も適切に解釈されますが、通常、[の存在ステータスは、trueまたはfalseとして最も適切に解釈されます。)

[がfalseを返した場合、ファイルはなくなっているため移動されたため、何もする必要はありません。ただし、[がfalseを返した場合、ファイルはまだ存在しています。次に、findは次の-exec式を評価し、警告メッセージを出力します。

さらに読む

9
Eliah Kagan