回答:
一般的に、ディレクトリとそのサブディレクトリ内のファイルを再帰的に検索する場合は、を使用しますfind
。
日付範囲を指定する最も簡単な方法find
は、範囲の境界でファイルを作成し、-newer
述語を使用することです。
touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop
-newer
ここで最初の出力を無効にする必要があるのはなぜですか?
-newer
は否定されず、2番目は否定されます。「より新しいがstart
、より新しいファイルを見つけるstop
」。
start
との両方よりも新しいファイルを取得します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でうまく機能します。
find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l
(-m 50
=最初の50行で検索)。
-exec ... +
in を使用してパイプとxargsを節約できます。これは同じことですが、安価です。find(1)
find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +
find 4.7.0-git
)。
秒の精度は必要ないと仮定すると、これは機能するはずです。
find . -type f -mmin -$(((`date +%s`-`date -d 20111222 +"%s"`)/60)) \! -mmin +$(((`date +%s`-`date -d 20111224 +"%s"`)/60))
編集: @Eelvexのコメントの後に変更さcmin
れましmmin
た。
編集: '\!' 行方不明
-cmin
「ステータス変更」、-mmin
「データ変更」です。おそらくしたい-mmin
重複としてマークされた質問は、直接回答することを制限されているため、ここに投稿することに注意してください。この回答は、「作成日に基づいてファイルを別のフォルダに移動する必要がある[重複]」という質問に答えるためのものです。
答えは合理的ですが、純粋にfindコマンドにはいくつかの制限がありました。このシェルスクリプトは、ファイルシステムが非常に多くのファイルを含むディレクトリを通過するように作成し、ファイルシステムがlsを実行しようとしてメタデータを吐き出していました。さらに、一部の* nixシステムでは、lsを実行すると引数が多すぎるというエラーが発生します。
findコマンドは非常に強力であり、リストされている方法から始めましたが、そのディレクトリ全体で長年のデータがあったため、すべてのファイルを繰り返し渡す必要がありました。これにより、各ファイルに不要な多くのパスが渡されます。1年に1つの画面を実行して複数の検索を実行しようとしましたが、これにより各検索から多くのエラーが発生し、検索の1つが移動するとファイルが失われていました。
私のシェルスクリプトは、4桁の年と2桁の月を使用して、ファイルを宛先ディレクトリに移動します。数行のコメントを外し、対応する行をコメントアウトすることで、簡単に2桁の日付に拡張できます。findの1回のパスで移動を実行し、複数のfindコマンドとディレクトリのパスが不要になるため、より効率的だと思います。
#!/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が提供するファイルごとに単一の実行が提供され、スクリプトがすべての決定を行うため、findのnewermtオプションの設定について心配する必要はありません。
-type fを選択しないと、ディレクトリが移動し、問題が発生する可能性があることに注意してください。ディレクトリだけを移動する場合は、-type dを使用することもできます。タイプを設定しないと、ほぼ確実に望ましくない動作が発生します。
このスクリプトは私に合わせて作成されたことを忘れないでくださいニーズ。ニーズのスクリプトにより適したものにするためのインスピレーションとして、単純に私の構成を使用することができます。ありがとうございました!
考慮事項:コマンドの効率は大きくなる可能性があります無制限の数の引数がスクリプトを通過できるようにする改善できます。これは、$ @変数を渡した場合、実際には比較的簡単です。この機能を拡張すると、たとえばfindの-exec +関数を使用したり、xargsを活用したりできます。私はすぐにそれを実装し、自分の答えを改善するかもしれませんが、これは始まりです。
これは1回限りのスクリプトセッションであったため、おそらく多くの改善が可能です。がんばろう!