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


21

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

ターミナル経由で、2011-01-01から2011-12-31までのファイルを見つけるためにfindを使用しようとしていますが、役に立ちません。

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

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


@EliahKagan当時、メモリが提供されていれば、重複した名前は問題になりませんでした。それにも関わらず、時間があることをフィードする場合、特定の主題に関する追加情報は常に高く評価されます:)また、このトピックに関する追加の洞察を提供するため、私はあなたの答えを投票しました。
ズール14年

@EliahKaganその場合、あなたが強調した実用的なフェイルセーフで答えを提供することをお勧めします:)
Zuul 14年

回答:


16

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

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

6
の出力は、ファイルの名前に空白スペースが含まれないことが保証されている場合を除き、このようなfindシェルforループで処理しないでください。-exec-execdir、または-print0 | xargs通常代わりに使用されるべきです。通常はあまり望ましくないが、forループの使用を許可する別の可能な解決策はIFS、スペースがフィールド区切り文字として認識されないように一時的に設定することです。
エリアケイガン14年

@EliahKaganはそう何を、その後のようなコマンドになります:ちょうどを交換するfindexec?スペースの使用に対処する回答を追加してもよろしいですか?とても有難い。
シェリルホーマン

3
@SherylHohmanいいえ、execコマンドを使用しないでください。実行findする-execアクションmv、または実行する必要があるものをコマンドで使用します。これについては、私が投稿た回答で説明しています。ときfind... -execそれが見つかったパス名を使用してコマンドを実行し、スペースがトリガされませんので、それは、シェルを使用していない単語の分割またはグロブを。(特定のケースに関する新しい質問を投稿するか、正確に知りたいことを尋ねることができます。)
エリアカガン

@EliahKagan申し訳ありませんが、あなたの投稿を読み間違えました-それはあなたからのものでした!あなたは素晴らしいです!あなたの投稿は素晴らしいです。そして、それは読んでの私自身のエラーでしたが、返信してくれてありがとう!
シェリルホーマン

40

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


10

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

以下のようSubv3rsionさんエリックLeschinskiの答えが表示され、-newermt述語選択したファイルは、そのオペランドとして指定した日付(およびオプションの時間)よりも多く、最近変更しました。ファイルを見つけるには

  • どこにでもsrcdir(つまり、そのサブディレクトリ、サブディレクトリなどを含む)
  • 最終変更日(たとえば)2014年9月
  • そしてそれらを移動します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/mvmv
  • その程度の対話性さえ必要とせず、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同じ名前の別のファイルがあったために移動されなかったファイルを使用して知りたい場合、おそらく最良の方法は、元の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式を評価します。

参考文献


私は時間を取得すると、私はパフォーマンスの考慮事項についてやセクションを追加したいと考えてい-exec ... +mv -t、いつかすぐに、。
エリアケイガン14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.