Làm thế nào để liệt kê các tập tin đã được thay đổi trong một khoảng thời gian nhất định?


38

Làm cách nào tôi có thể liệt kê đệ quy tất cả các tệp đã được thay đổi trong khoảng thời gian từ 22.12.2011 đến 24.12.2011?


6
Nếu bạn có nghĩa là 'thay đổi lần cuối', bạn có cơ hội giải pháp. Nếu một tệp đã được sửa đổi vào ngày 26.12.2011, bạn không thể biết liệu nó cũng đã được sửa đổi trong phạm vi đã cho hay chưa. (Trừ khi bạn có một hệ thống tệp rất kỳ lạ.)
William Pursell

Câu trả lời:


25

Nói chung, khi bạn đang tìm kiếm các tệp trong một thư mục và các thư mục con của nó theo cách đệ quy, hãy sử dụng find.

Cách dễ nhất để xác định phạm vi ngày findlà tạo các tệp ở ranh giới của phạm vi và sử dụng -newervị ngữ.

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

Tại sao phủ nhận đầu ra của đầu tiên -newerlà cần thiết ở đây?
Alexander Cska

@AlexanderCska Cái đầu tiên -newerkhông bị phủ định, cái thứ hai là. Tập tin Tìm các tập tin mới hơn startnhưng không mới hơn tập tin stop.
Gilles 'SO- ngừng trở nên xấu xa'

Ok phủ định hoạt động trên lệnh sau. Điều gì sẽ xảy ra nếu không có sự phủ định?
Alexander Cska

@AlexanderCska Sau đó, bạn sẽ nhận được các tệp mới hơn cả startstop.
Gilles 'SO- ngừng trở thành ác quỷ'

35

Sử dụng giải pháp của Gilles và sau khi đọc lại, người đàn ông tìm thấy (1) một lần nữa tôi tìm thấy một giải pháp đơn giản hơn. Tùy chọn tốt nhất là -newerXY. Các cờ m và t có thể được sử dụng.

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

Vì vậy, giải pháp là

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

Giới hạn dưới bao gồm, và giới hạn trên là độc quyền, vì vậy tôi đã thêm 1 ngày vào đó! Và nó là đệ quy. Nó hoạt động tốt trên tìm v4.5.9.


Thủ thuật hay, cảm ơn! Điều đó giúp tôi tìm thấy một tệp gần đây có chứa một từ khóa nhất định trong một thư mục có hàng ngàn tệp: find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l( -m 50= tìm kiếm trong 50 dòng đầu tiên).
Rob W

@RobW: Thực ra bạn có thể dành ra một số đường ống và xargs sử dụng -exec ... +trong find(1), như: find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +. Điều này không giống nhau, nhưng rẻ hơn.
TrueY

Tôi đã phải kèm theo dấu thời gian với dấu ngoặc kép (Tôi đang sử dụng Ubuntu Xenial find 4.7.0-git).
IsaacS

13

Ngoài các câu trả lời đã được đưa ra, lưu ý rằng bạn có thể trực tiếp chỉ định ngày của mình:

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

hoặc là

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

nếu bạn muốn thêm thời gian.


6

Giả sử bạn không cần độ chính xác đến từng giây, điều này sẽ hoạt động.

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

EDIT: Thay đổi cminthành mminsau bình luận của @ Eelvex. CHỈNH SỬA: '\!' còn thiếu


hm dường như không hoạt động bạn có chắc chắn rằng nó đệ quy đi qua các thư mục con?
kẹp

Vâng, nó hoạt động trên tôi. Bạn có thực sự có các tập tin được sửa đổi trong phạm vi thời gian đó? Hãy thử nó với các phạm vi thời gian khác nhau.
onur güngor

6
-cminlà "thay đổi trạng thái", -mminlà "thay đổi dữ liệu". Bạn có thể muốn-mmin
Eelvex

3

findcó thể lấy một datetime định dạng ISO, vì vậy, đối với một máy chủ trên UTC chẳng hạn, bạn có thể chỉ định một phần bù của một số giờ từ bất cứ nơi nào bạn đang ở. Điều này cũng quan tâm đến việc phải thêm một ngày vì bạn cũng đang so sánh thời gian:

find -type f -newermt 20111224T0800 \! -newermt 20111225T0800

0

Xin lưu ý rằng câu hỏi được đánh dấu là trùng lặp và do đó bị hạn chế trả lời trực tiếp, đó là lý do tại sao tôi đăng bài vào đây. Câu trả lời này là để trả lời câu hỏi "cần di chuyển tệp đến thư mục khác dựa trên ngày tạo [trùng lặp]"

Các câu trả lời là hợp lý nhưng có một số hạn chế với lệnh hoàn toàn tìm thấy. Tôi đã viết kịch bản shell này để đi qua một thư mục có rất nhiều tệp trong đó hệ thống tệp đang bịt miệng trên siêu dữ liệu đang cố gắng thực hiện một ls. Ngoài ra, một số hệ thống * nix sẽ xử lý quá nhiều lỗi đối số khi chạy ls.

Lệnh find rất mạnh mẽ và tôi đã bắt đầu với các phương thức được liệt kê nhưng tôi đã có rất nhiều năm dữ liệu trong thư mục đó đến nỗi tôi phải chuyển qua tất cả các tệp nhiều lần. Điều này tạo ra rất nhiều không cần thiết thông qua mỗi tập tin. Tôi đã thử thực hiện một màn hình mỗi năm và chạy nhiều kết quả tìm kiếm nhưng điều này dẫn đến rất nhiều lỗi từ mỗi lần tìm và các tệp sẽ bị mất khi một trong các kết quả tìm thấy di chuyển nó.

Kịch bản shell của tôi di chuyển một tập tin vào thư mục đích, với một năm gồm 4 chữ số và một tháng có 2 chữ số. Nó có thể dễ dàng được mở rộng đến một ngày gồm 2 chữ số bằng cách bỏ qua một vài dòng và nhận xét các đối tác của họ. Tôi tin rằng nó hiệu quả hơn vì nó đã thực hiện các động tác trong một lần tìm kiếm nên nhiều lệnh tìm và chuyển qua thư mục là không cần thiết.

#!/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

Sau khi lưu và thực hiện, bạn có thể gọi tập lệnh này với tìm như sau.

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

Bạn không cần phải lo lắng về việc đặt tùy chọn newermt để tìm vì tất cả các tìm kiếm đang cung cấp là một thực thi duy nhất cho mỗi tệp được tìm thấy và tập lệnh đưa ra tất cả các quyết định.

Hãy nhớ rằng nếu bạn không chọn -type f, nó sẽ di chuyển các thư mục xung quanh và điều đó có thể sẽ gây ra sự cố. Bạn cũng có thể sử dụng -type d nếu bạn đang muốn chuyển chỉ các thư mục. Không thiết lập loại gần như chắc chắn sẽ tạo ra hành vi không mong muốn.

Hãy nhớ rằng kịch bản này đã được điều chỉnh theo nhu cầu của tôi . Bạn có thể muốn sử dụng cấu trúc của tôi như một nguồn cảm hứng để phù hợp hơn với kịch bản nhu cầu của bạn. Cảm ơn bạn!

Cân nhắc: Hiệu quả của lệnh có thể được cải thiện TUYỆT VỜI bằng cách cho phép số lượng đối số không giới hạn đi qua tập lệnh. Điều này thực sự tương đối dễ dàng nếu bạn vượt qua biến $ @. Mở rộng chức năng của điều này sẽ cho phép chúng tôi sử dụng chức năng find -exec + hoặc tận dụng xargs chẳng hạn. Tôi có thể nhanh chóng thực hiện điều đó và cải thiện câu trả lời của riêng tôi nhưng đây là một sự khởi đầu.

Vì đây là phiên kịch bản một lần, có lẽ có nhiều cải tiến có thể được thực hiện. Chúc may mắn!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.