年に基づいてファイルを移動する方法


14

1年ごとにファイルを移動する必要があります。findコマンドを使用しました

find /media/WD/backup/osool/olddata/ -mtime +470 -exec ls -lrth {} \;|sort -k6

しかし、このコマンドを正常に実行するには、正確な値を知る必要がありmtimeます。2012年を指定できる場合は、2012年に関連するファイルのみが提供されます。

だから私は方法についてのアドバイスが必要です

2012年などの年に基づいてファイルを検索し、他のディレクトリに移動します。

OS release 5.2

FIND version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX 

-exec ls ... \;代わりに使用するのは理にかなっています-exec ... +か?あなたの発見は古すぎますか?その場合find ... -print0 | xargs -0 ls...、はるかに高速になります。
ハウケレイジング

coreutilsを扱うこれらの質問(および回答)が、GNUまたはBSD(またはその他の)utilsのどちらを扱っているかを定期的に指定することを望みます。
ラビリンス14年

回答:


37

次の-newermtオプションを使用しますfind

find /media/WD/backup/osool/olddata/ -newermt 20120101 -not -newermt 20130101

2012年の変更時間ですべてのファイルを取得します。

検索結果がサポートされ-newermtていない場合は、次の操作を行ってオフセット計算の使用を防ぐこともできます。

touch -d 20120101 /var/tmp/2012.ref
touch -d 20130101 /var/tmp/2013.ref
find /media/WD/backup/osool/olddata/ -newer /var/tmp/2012.ref -not -newer /var/tmp/2013.ref

1
-newermtフラグは、検索コマンドでは使用できません
OmiPenguin

これは、RHELに付属しているfindの古いバージョンである必要がありますか?私はその答えに代替案を提供します
アントン

はい、これは5.2です
近江ペンギン

私は、RHELの改訂版であること、それを取らないのfind(私はバージョン4.4.2を見つける持っている)
Anthonの

1
newermtスイッチは、v4.3.3、gnu.org / software / findutils / manual / html_mono / find.html以降のバージョンまでfindに表示されませんでした
slm

5
touch --date=2011-12-31T23:59:59 start
touch --date=2012-12-31T23:59:59 stop
find / -newer start \! -newer stop -printf %Tx" "%p\\n

-exec ls 意味がありません。


1
-exec ls -lより理にかなっており、テスト中にさらに意味があります。
CVn

@MichaelKjörling findはすべてを印刷できますls可能なできます。ただし、1つの例外があります。不快な文字のエスケープ/引用。しかし、一般的にの出力はfind直接ソートできます。lsの無用な呼び出しは、全体を高速化するものではありません。
ホークレイジング

私はテスト中に非常によく似たものを非常によく使用します(個人的には私が好む-printか、おそらく -ls)。を使用する利点-exec ls {}、findの外部の何かをすでに実行していることです。そのlsためmv、からに切り替えるまでに、実際の変更はごくわずかです。
CVn

3

マニュアルページによると、-mtimeの引数は、探している日数です。を使用date +%jして、現在の年の1月1日からの日数を見つけることができます。


2
いい方法。非常に「鋭敏」であるために:-mtime -1:過去24時間の任意のファイル。昨日(または今日)のファイルだけではありません。そのため、「オーバーラップ」も少し発生します。2012年から120日が経過し、今日スクリプトを起動すると15:45であると判断した場合、最終的に12月31日15:45(その日の最後ではありません)...あなたはおそらく使用することができます:nb_day-1、それから2013年からの数人を「除草」します(これらはls -l | grep -v、BUTで見つけることができます) 1日前の場合は出力が異なります...たくさんの落とし穴...)
オリビエデュラック

を使用する-daystart場合は、このオプションを使用する必要があります-mtime。そうしないと、これを正確に真夜中に実行しない限り、どのように方向を変えても、年の初めと終わり頃にファイルに問題が発生します。新年からの分数を簡単に見つけることができる場合-mminよりも、より正確にオフセットを行う-mtimeことができます。ただし、の場合と同じ問題があり-mtimeますが、ファイルの数が少ない(新年の真夜中の1分)だけです。
アントン

1
ええ、マニュアルページを読み直すと、それが何時間に分割されるかがわかります。そのため、単純な操作を行ってもfind -mtime $("date -+%j")、OPが目的を達成できない可能性があります。私は後世のためにそれを残していますが、これは人々が陥る可能性のある盲点のように見えるからです。
ブラッチリー

2

次のワンライナーのように、statand / or dateコマンドと組み合わせて使用​​してみてください。

BSD / Mac OS X:

find . -type f -print | while read file; do eval `stat -s "$file"`; year=`date -jf "%s" "+%Y" "$st_mtime"`; dest="/path/to/destination/$year; mkdir -p "$dest"; mv "$file" "$dest"; done

Linux:

find . -type f -print | while read file; do year=`date -r "$file" "+%Y"`; dest="/path/to/destination/$year; mkdir -p "$dest"; mv "$file" "$dest"; done

どちらの場合も、アプローチはdateコマンドを使用して、すべてのファイルの最終変更時刻から年を抽出し、その年でパスを構築することです。mkdir -pこのパスがまだ存在しない場合、コマンドはこのパスを作成します。もちろん、他のfindオプションを使用して検索を絞り込むことができます。


1

作業ディレクトリからこれを行う場合、代わりにこれを行うことができます。

ls -l |awk '{ if ($8 == "2013") print $9 }'

これにより物事が大幅に簡素化され、オーバーラップが発生しません。ただし、これらのファイルは6か月以上前のものであり、ls、正確な時刻ではなく年を印刷する。

6か月前より新しいファイルについては、次のように置き換えるだけです。

ls -l |awk '{ if ($6 == "May") print $9 }' 

または月に応じて類似した何か。ファイルを移動する月のリストを作成する場合(または年のリストを作成する場合)は、次のようにします。

month="May Jun Jul"; 
for i in `echo $month`; 
do 
    for j in `ls -l |awk '{ if ($6 == "'$i'") print $9}'`
    do
        mkdir -p $i
        mv $j $i
    done
done
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.