私は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/
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
同じ名前の別のファイルがあったために移動されなかったファイルを使用して知りたい場合、おそらく最良の方法は、元の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
述語は、戻り値に使用されるテスト(-type
andなど-newermt
)、または副作用(副作用)によく使用されるアクション(-print
andなど-exec
)になります。
式の間に演算子(-a
for や、-o
for や)が指定されていない場合-a
は、暗示されます。andおよびorに対して短絡評価をfind
採用しています。(つまり、)は、p式とq式の両方が真である場合にのみ真であるため、pが偽の場合、qを評価する必要はありません。私たちはこれらの用語でそれをしばしば考えませんが、これは評価されるべき後続のアクションまたはテストに対してテストが真実でなければならない理由です。たとえば、ディレクトリにアクセスするとします。false と評価されるため、その後すべてをスキップできます。p q
p -a q
find
-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を返します。(多くのコマンドの終了ステータスは成功または失敗を示すものとして最も適切に解釈されますが、通常、存在ステータスは真または偽として最も適切に解釈されます。)-f
find
{}
[
[
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
、いつかすぐに、。