web-dev-qa-db-ja.com

特定の期間に変更されたファイルを一覧表示するにはどうすればよいですか?

2011年12月22日から2011年12月24日の間に変更されたすべてのファイルを再帰的に一覧表示するにはどうすればよいですか?

40
clamp

一般的に、ディレクトリとそのサブディレクトリでファイルを再帰的に検索する場合は、findを使用します。

findで日付範囲を指定する最も簡単な方法は、範囲の境界にファイルを作成し、-newer述語を使用することです。

touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop

Gillesのソリューションを使用し、 man find(1) を再度読んだ後、私はより簡単なソリューションを見つけました。最良のオプションは-newerXYです。 mフラグとtフラグを使用できます。

m   The modification time of the file reference
t   reference is interpreted directly as a time

だから解決策は

find . -type f -newermt 20111222 \! -newermt 20111225

下限は包括的、上限は排他的であるため、1日を追加しました。そしてそれは再帰的です。 Find v4.5.9でうまく機能します。

38
TrueY

すでに与えられた回答に加えて、日付を直接指定できることに注意してください:

find -type f -newermt "2011-12-22" \! -newermt "2011-12-24"

または

find -type f -newermt "2011-12-22 00:00:00" \! -newermt "2011-12-24 13:23:00"

さらに時間を指定したい場合。

15
student

秒の精度が必要ない場合は、これでうまくいくはずです。

find . -type f -mmin -$(((`date +%s`-`date -d 20111222 +"%s"`)/60)) \! -mmin +$(((`date +%s`-`date -d 20111224 +"%s"`)/60))

編集: @Eelvexのコメントの後にcminmminに変更しました。 編集: '\!'行方不明

6
onur güngör

findはISO形式の日時を取得できるため、たとえばUTCのサーバーの場合、どこからでも時間数のオフセットを指定できます。これも時間を比較しているので、1日を追加する必要があります。

find -type f -newermt 20111224T0800 \! -newermt 20111225T0800
3
Alex Young

重複としてマークされているため、直接回答することが制限されている質問は、ここに投稿する理由です。この回答は、「作成日に基づいてファイルを別のフォルダに移動する必要があります[重複]」という質問に答えるためのものです。

答えは妥当ですが、純粋にfindコマンドにはいくつかの制限がありました。私はこのシェルスクリプトを記述して、非常に多くのファイルが含まれるディレクトリを経由して、ファイルシステムがlsを実行しようとするメタデータを調べていました。さらに、一部の* nixシステムでは、lsの実行時に引数エラーが多すぎます。

Findコマンドは非常に強力で、リストにあるメソッドから始めましたが、そのディレクトリ全体に何年ものデータがあり、すべてのファイルを繰り返し渡さなければなりませんでした。これにより、各ファイルに多くの不要なパスが渡されます。毎年1つの画面を実行して複数の検索を実行しようとしましたが、これにより各検索から多くのエラーが発生し、検索の1つが移動するとファイルが失われました。

私のシェルスクリプトは、4桁の年と2桁の月を含むファイルを宛先ディレクトリに移動します。数行のコメントを外して対応する行をコメント化することで、2桁の日付に簡単に拡張できます。検索の1つのパスで移動を実行したため、複数の検索コマンドとディレクトリのパスが不要なので、より効率的だと思います。

#!/bin/bash
#We want to exit if there is no argument submitted
if [ -z "$1" ]
then
  echo no input file
  exit
fi

#destDir should be set to where ever you want the files to go
destDir="/home/user/destination"

#Get the month and year of modification time
#--format %y returns the modification date in the format:
# 2016-04-26 12:40:48.000000000 -0400
#We then take the first column, split by a white space with awk
date=`stat "$1" --format %y | awk '{ print $1 }'`

#This sets the year variable to the first column split on a - with awk
year=`echo $date | awk -F\- '{print $1 }'`
#This sets the month variable to the second column split on a - with awk
month=`echo $date | awk -F\- '{print $2 }'`
#This sets the day variable to the third column split on a - with awk
#This is commented out because I didn't want to add day to mine
#day=`echo $date | awk -F\- '{print $3 }'`

#Here we check if the destination directory with year and month exist
#If not then we want to create it with -p so the parent is created if
# it doesn't already exist
if [ ! -d $destDir/$year/$month ]
then
  mkdir -p $destDir/$year/$month || exit
fi

#This is the same as above but utilizes the day subdirectory
#Uncommented this out and comment out the similar code above
#if [ ! -d $destDir/$year/$month/$day ]
#then
#  mkdir -p $destDir/$year/$month$day || exit
#fi

#Echoing out what we're doing
#The uncommented is for just year/month and the commented line includes day
#Comment the first and uncomment the second if you need day
echo Moving $1 to $destDir/$year/$month
#echo Moving $1 to $destDir/$year/$month/$day

#Move the file to the newly created directory
#The uncommented is for just year/month and the commented line includes day
#Comment the first and uncomment the second if you need day
mv "$1" $destDir/$year/$month
#mv "$1" $destDir/$year/$month/$day

保存して実行可能にしたら、次のようなfindを使用してこのスクリプトを呼び出すことができます。

find /path/to/directory -type f -exec /home/username/move_files.sh {} \;

すべてのfindが提供するのは、見つかったファイルごとに1回の実行であり、スクリプトがすべての決定を行うため、findのnewermtオプションの設定について心配する必要はありません。

-type fを選択しないと、ディレクトリが移動し、問題が発生する可能性があることに注意してください。ディレクトリだけを移動する場合は、-type dを使用することもできます。タイプを設定しないと、ほぼ確実に不要な動作が発生します。

このスクリプトはmyのニーズに合わせて調整されたことを思い出してください。あなたは単にあなたのニーズスクリプトにより適したインスピレーションとして私の構成を使用したいかもしれません。ありがとうございました!

考慮事項:コマンドの効率は[〜#〜] greatly [〜#〜]無制限の数の引数がスクリプトを通過できるようにすることで改善できます。 $ @変数を渡すと、これは実際には比較的簡単です。この機能を拡張すると、たとえば、findの-exec +関数を使用したり、xargsを利用したりできます。私はすぐにそれを実装して自分の答えを改善するかもしれませんが、これは始まりです。

これはワンショットのスクリプトセッションだったので、おそらく多くの改善が可能です。幸運を!

0
Vex Mage