Cara menghapus file yang lebih lama dari X jam

191

Saya sedang menulis skrip bash yang perlu menghapus file lama.

Saat ini diterapkan menggunakan:

find $LOCATION -name $REQUIRED_FILES -type f -mtime +1 -delete

Ini akan menghapus file yang lebih lama dari 1 hari.

Namun, bagaimana jika saya membutuhkan resolusi yang lebih baik dalam 1 hari, katakanlah seperti 6 jam? Apakah ada cara bersih yang bagus untuk melakukannya, seperti menggunakan find dan -mtime?

Tom Feiner
sumber

Jawaban:

303

Apakah Anda findpunya -mminpilihan? Itu dapat memungkinkan Anda menguji jumlah menit sejak modifikasi terakhir:

find $LOCATION -name $REQUIRED_FILES -type f -mmin +360 -delete

Atau mungkin terlihat menggunakan tmpwatchuntuk melakukan pekerjaan yang sama. phjr juga direkomendasikan tmpreaperdalam komentar.

Paul Dixon
sumber
2
Menggunakan --mmin + X mengembalikan semua file dengan temuan saya. Kesalahan saya karena tidak memeriksa ini dulu, tetapi perintah ini baru saja menghapus sebagian besar direktori home saya. Bagi saya, --mmin -X adalah argumen yang benar.
brandones
tmpreaper adalah garpu dari tmpwatch. Itu lebih aman, dan ada sebagai paket debian di distro. Manfaat lebih dari -delete: tmpreaper tidak akan menghapus symlink, soket, fifos, atau file khusus
Nadir
Tunjukkan bahwa $ REQUIRED_FILES harus dalam tanda kutip (tanda kutip ganda) dan Anda dapat menggunakan pola seperti: " .txt" untuk semua file .txt atau file yang dimulai dengan pola seperti: "temp- " untuk menghapus semua file yang dinamai dengan temp -
achasinh
@ PaulDixon cara memodifikasi ini sehingga $LOCATIONdan $REQUIRED_FILESdapat keduanya memiliki beberapa nilai seperti dir1 dir2dan *.txt *.tmp?
Enissay
@Enissay $ LOCATION adalah direktori tunggal. Untuk beberapa ekstensi, Anda mungkin ingin menggunakan pola dengan -regex - lihat stackoverflow.com/questions/5249779/…
Paul Dixon
9

Anda dapat melakukan trik ini: membuat file 1 jam yang lalu, dan menggunakan -newer fileargumen.

(Atau gunakan touch -tuntuk membuat file seperti itu).

xtofl
sumber
1
tidak ada saklar -older (setidaknya dalam perintah find saya), dan itulah yang akan dibutuhkan. -Newer tidak membantu.
iconoclast
dapatkah Anda memberikan perintah sentuh yang akan menghasilkan file berumur 1 jam yang akan bekerja pada mesin yang tidak bisa menggunakan -mmin? (Jika Anda menggunakan Linux, -mmin tersedia, jika tidak maka tanggal dan perintah lain juga lemah dibandingkan.)
iconoclast
2
@iconoclast touch -t $(date -d '-1 hour' +%Y%m%d%H%M.00) testMembuat file testyang selalu berumur 1 jam.
rovr138
4

Inilah pendekatan yang berhasil untuk saya (dan saya tidak melihatnya digunakan di atas)

$ find /path/to/the/folder -name *.* -mmin +59 -delete > /dev/null

menghapus semua file yang lebih lama dari 59 menit sambil membiarkan folder tetap utuh.

Axel Ronsin
sumber
Lebih baik untuk kutipan tunggal '*.*'atau shell akan memperluas ke nama file yang sebenarnya daripada menyimpannya sebagai wildcard untuk finddiselesaikan. Ini memecah findoperasi rekursif pada subdir.
MestreLion
Juga perlu diingat bahwa -name '*.*'tidak akan menghapus file yang tidak memiliki ekstensi, seperti README, Makefile, dll
MestreLion
1

Untuk SunOS 5.10

 Example 6 Selecting a File Using 24-hour Mode


 The descriptions of -atime, -ctime, and -mtime use the  ter-
 minology n ``24-hour periods''. For example, a file accessed
 at 23:59 is selected by:


   example% find . -atime -1 -print




 at 00:01 the next day (less than 24 hours  later,  not  more
 than one day ago). The midnight boundary between days has no
 effect on the 24-hour calculation.
Rajeev Rumale
sumber
0

-min adalah selama beberapa menit.

Coba lihat halaman manual.

man find

untuk lebih banyak tipe.

GavinCattell
sumber
0

Jika Anda tidak memiliki "-mmin" di versi "find", maka "-mtime -0.041667" mendekati "dalam satu jam terakhir", jadi dalam kasus Anda, gunakan:

-mtime +(X * 0.041667)

jadi, jika X berarti 6 jam, maka:

find . -mtime +0.25 -ls

bekerja karena 24 jam * 0,25 = 6 jam

Malcolm Boekhoff
sumber
Sangat berharap karena UNIX lama ini tidak memiliki -mmin, tetapi, sayangnya ini tidak membantu karena UNIX lama ini juga tidak suka nilai fraksional untuk mtime: find: argumen to -mtime harus bilangan bulat dalam rentang -2147483647 untuk 2147483647
kbulgrien
0

Inilah yang dapat dilakukan seseorang untuk melanjutkan cara @iconoclast bertanya-tanya tentang komentar mereka pada jawaban lain.

gunakan crontab untuk pengguna atau /etc/crontabuntuk membuat file /tmp/hour:

# m h dom mon dow user  command
0 * * * * root /usr/bin/touch /tmp/hour > /dev/null 2>&1

dan kemudian gunakan ini untuk menjalankan perintah Anda:

find /tmp/ -daystart -maxdepth 1 -not -newer /tmp/hour -type f -name "for_one_hour_files*" -exec do_something {} \;
satyr0909
sumber
*/1untuk setiap jam adalah berlebihan di crontab Anda. Ini sama dengan menempatkan * di bidang jam.
colm.anseo
0

find $PATH -name $log_prefix"*"$log_ext -mmin +$num_mins -exec rm -f {} \;

Eragonz91
sumber
0

Jika seseorang findtidak memiliki -mmindan jika seseorang juga terjebak dengan findyang hanya menerima nilai integer -mtime, maka semua tidak selalu hilang jika seseorang menganggap bahwa "lebih tua dari" mirip dengan "tidak lebih baru dari".

Jika kami dapat membuat file yang memiliki batas waktu cut-off kami, kami dapat meminta finduntuk mencari file yang "tidak lebih baru dari" file referensi kami.

Untuk membuat file yang memiliki waktu yang benar cap adalah sedikit terlibat karena sistem yang tidak memiliki cukup findmungkin juga memiliki kurang mampu dateperintah yang bisa melakukan hal-hal seperti: date +%Y%m%d%H%M%S -d "6 hours ago".

Untungnya, alat lama lain yang dapat mengelola ini, meskipun dengan cara yang lebih sulit.

Anggap enam jam adalah 21600 detik. Kami ingin menemukan waktu enam jam yang lalu dalam format yang bermanfaat:

$ date && perl -e '@d=localtime time()-21600; \
  printf "%4d%02d%02d%02d%02d.%02d\n", $d[5]+1900,$d[4]+1,$d[3],$d[2],$d[1],$d[0]'
> Thu Apr 16 04:50:57 CDT 2020
202004152250.57

Pernyataan perl memang menghasilkan tanggal yang bermanfaat, tetapi harus dimanfaatkan dengan lebih baik:

$ date && touch -t `perl -e '@d=localtime time()-21600; \
  printf "%4d%02d%02d%02d%02d.%02d\n", \
  $d[5]+1900,$d[4]+1,$d[3],$d[2],$d[1],$d[0]'` ref_file && ls -l ref_file
Thu Apr 16 04:53:54 CDT 2020
-rw-rw-rw-   1 root     sys            0 Apr 15 22:53 ref_file

Sekarang solusi untuk UNIX lama ini adalah sesuatu seperti:

$ find . -type f ! -newer ref_file -a ! -name ref_file -exec rm -f "{}" \;

Mungkin juga merupakan ide bagus untuk membersihkan file referensi kami ...

$ rm -f ref_file
kbulgrien
sumber