シェルスクリプト— <date>以降に変更されたすべてのファイルを取得します


136

私はPHPではこれをしたくないので、シェルスクリプトに詳しい人が助けてくれることを願っています。

ディレクトリを再帰的に実行し、最終更新日がすべてのファイルを特定の日付よりも後の日付で見つけるスクリプトが必要です。次に、パス情報を保持したままファイルをtarおよびzip圧縮します。


14
PHPでそれを行わないという良い決断です。
クレデンス2009年

1
phpに頼ることなく、python、ruby、perlなどの適切なシェルスクリプト言語を使用できます。
ガロウ2009年

3
@garrowこれは実際には、PHPではFilterIteratorに連結されたRecursiveDirctoryIteratorを使用することでかなり簡単です。
Artefacto 2010年

回答:


136

単純な:

find . -mtime -1 | xargs tar --no-recursion -czf myfile.tgz

は、find . -mtime -1前日に変更された(再帰的に)現在のディレクトリにあるすべてのファイルを選択します。たとえば、分数を使用できます。

find . -mtime -1.5 | xargs tar --no-recursion -czf myfile.tgz

4
ファイル名のスペースを処理する方法については、以下のuser104848の回答を参照してください
Brian Henk

8
任意のタイムスタンプを小数の相対時間に変換することは、正確でも特に便利でもありません。以下のソリューションを使用する-newermtと、はるかに優れています。
ボビージャック

5
ディレクトリのある構造に変更のあるファイルを抽出しようとすると、ディレクトリ自体が変更済みとしてマークされ、フォルダ全体がアーカイブされます。-type f選択したファイルのみに追加します。これはフォルダ構造を維持しますが、変更のあるファイルのみをバックアップします。
ブレント

1
@BrianHenk user104848が自分の名前を変更し、私はかなり確信して、あなたは意味しています(現在は)ジェイソン・ルーサーからこの答えをけれども
icc97

4
この質問では、任意の日付でファイルを検索するよう求められます。この答えは、過去の任意の日数でファイルを見つける方法です。日付を日差に変換するステップを追加しない限り、これは受け入れられる答えではないと思います。
マーク

91

GNUを使用している場合findは、関連するオプションが多数あります。唯一の問題は、それらへのインターフェースが優れていることです。

  • -mmin n (分単位の変更時間)
  • -mtime n (変更日数)
  • -newer file (ファイルの変更時刻より新しい変更時刻)
  • -daystart (開始時刻を現在時刻から1日の始まりに調整)
  • さらに、アクセス時間と「変更」または「作成」時間の代替案。

難しいのは、時間からの分数を決定することです。

検討する価値のある1つのオプション:を使用touchして、必要な変更タイムスタンプを含むファイルを作成します。次にで使用find-newerます。

touch -t 200901031231.43 /tmp/wotsit
find . -newer /tmp/wotsit -print
rm -f /tmp/wotsit

これは、2009-01-03T12:31:43より新しいファイルを探します。明らかに、スクリプトで/tmp/wotsitは、一意にするためにPIDまたはその他の値を含む名前になります。そしてtrap、ユーザーが中断した場合などに確実に削除されるようにする必要があります。


65
代わりに、を使用-newermt '2009-01-03T12:31:43'して、参照用のファイルを作成する必要を回避できます。
Michael Mior

@MichaelMior:興味深い-MacOS X 10.7.2での「検索」はサポートされています-newermt-newerXY複数のオプションがあるため、以下に記載されています。この場合、X = m、Y = t)。私が使用する(ほとんど古い)LinuxシステムでのGNU findはオプションをサポートしていないため、比較的最近のリリースです。ヘッドアップをありがとう。
ジョナサンレフラー

このオプションは、私のシステムで使用しているGNU find 4.4.2にあります。
Michael Mior

2
また、GNU findは相対時間もサポートしていることにも注意してください。-newermt '-2 weeks'
Cybolic 2016年

1
-newermt '2009-01-03T12:31:43'見た目は素晴らしいですが、残念ながら間違ったタイムゾーンですべてを解釈しているようです。lists.gnu.org
archive

35

これはtarを使用して直接行うことができます。

tar -N '2014-02-01 18:00:00' -jcvf archive.tar.bz2 files

これは、2014年1月1日18:00:00より新しいファイルを圧縮するようにtarに指示します。


9
ええと...私は1984年以来Unixを使用していて、これを知らなかった。常に何かを学ぶ。
ジョン

その実装にはtar、OS XとFreeBSDのみがサポート--newer-Nれていますtar。これは、GNUの長いオプションです。
nisetama 2016年

これはすごいです... -xcvfとgz拡張を使用せずに、bzipでのみ動作させることができました...しかし、私は専門家ではありません。
フィル2017

17

これは、いくつかのファイルで機能します。パスにスペースが含まれている場合に備えて、「-print0」と「xargs -0」を含めます。この例では、過去7日間に変更されたファイルを探します。過去7日前に変更されたものを見つけるには、「+ 7」を使用します。

find . -mtime -7 -print0 | xargs -0 tar -cjf /foo/archive.tar.bz2

このページを警告し、xargsが、引数が多い場合は、tarコマンドを複数回実行させることができ、そして「-c」フラグが問題を引き起こす可能性があります。その場合は、次のようにします。

find . -mtime -7 -print0 | xargs -0 tar -rf /foo/archive.tar

圧縮されたtarアーカイブをtarで更新することはできないため、2番目のステップでbzip2またはgzipする必要があります。


1
2番目の点については、Gnu tarの-zオプションのようなgzip対応のtarコマンドを使用して、zipアーカイブを更新することもできます。
Suncat2000、2011

または、 'j'オプションを追加して、最近のGNU tarでbzipを使用します
hd1

3
上でジョナサンの答えについて述べたように、これにより、すべてのファイルがインポートされる原因となる変更を含むフォルダーが取得されます。-type f選択したファイルのみに追加します。これはフォルダ構造を維持しますが、最近変更/追加されたファイルのみをバックアップします。
ブレント

12

これにより、過去7日以内に変更されたすべてのファイルが表示されます。

find . -type f -mtime -7 -print

それをtar / zipにパイプすると、問題ないはずです。


3

Linuxの下でも、findコマンドのmanページを読んでみてください

man find

このようなものは

 find . -type f -mtime -7 -print -exec cat {} \; | tar cf - | gzip -9

そしてあなたはそれを持っています


3

次のコマンドを使用すると、x日前に最後に変更されたファイルのリストを取得できます。

find . -mtime -x

次に、結果のリストのファイルをtarおよびzipする必要があります。例:

tar czvf mytarfile.tgz `find . -mtime -30`

先月中に変更されたすべてのファイル。


3
"-mtime x"は "x"日前に変更されたファイルに一致します。 "-mtime -x"を使用して、 "x"日前に変更されたファイルに一致させます。
ランスリチャードソン

3

次のようにして、7日前のすべての新しいファイルをバックアップします

tar --newer $(date -d'7 days ago' +"%d-%b") -zcf thisweek.tgz .

「7日前」をニーズに合ったものに置き換えることもできます。

することができます: date -d'yesterday' +"%d-%b"

あるいは : date -d'first Sunday last month' +"%d-%b"


2

このスクリプトは、指定された日付の前後2分の変更日付を持つファイルを検索します(要件に応じて条件の値を変更できます)

PATH_SRC="/home/celvas/Documents/Imp_Task/"
PATH_DST="/home/celvas/Downloads/zeeshan/"

cd $PATH_SRC
TODAY=$(date  -d "$(date +%F)" +%s)
TODAY_TIME=$(date -d "$(date +%T)" +%s)


for f in `ls`;
do
#       echo "File -> $f"
        MOD_DATE=$(stat -c %y "$f")
        MOD_DATE=${MOD_DATE% *}
#       echo MOD_DATE: $MOD_DATE
        MOD_DATE1=$(date -d "$MOD_DATE" +%s)
#       echo MOD_DATE: $MOD_DATE

DIFF_IN_DATE=$[ $MOD_DATE1 - $TODAY ]
DIFF_IN_DATE1=$[ $MOD_DATE1 - $TODAY_TIME ]
#echo DIFF: $DIFF_IN_DATE
#echo DIFF1: $DIFF_IN_DATE1
if [[ ($DIFF_IN_DATE -ge -120) && ($DIFF_IN_DATE1 -le 120) && (DIFF_IN_DATE1 -ge -120) ]]
then
echo File lies in Next Hour = $f
echo MOD_DATE: $MOD_DATE

#mv $PATH_SRC/$f  $PATH_DST/$f
fi
done

たとえば、指定された日付よりも前の変更日を持つファイルが必要な場合、パラメーターの条件を破棄1200$DIFF_IN_DATEパラメーターを変更$DIFF_IN_DATE1できます。

あなたはファイルが指定した日付の前と後の変更日1時間を持つたい場合は同様に、単に置き換える120ことにより、3600の中でif CONDITION

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.