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?
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?
Câu trả lời:
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 find
là tạo các tệp ở ranh giới của phạm vi và sử dụng -newer
vị ngữ.
touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop
-newer
là cần thiết ở đây?
-newer
không bị phủ định, cái thứ hai là. Tập tin Tìm các tập tin mới hơn start
nhưng không mới hơn tập tin stop
.
start
và stop
.
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.
find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l
( -m 50
= tìm kiếm trong 50 dòng đầu tiên).
-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.
find 4.7.0-git
).
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 cmin
thành mmin
sau bình luận của @ Eelvex.
CHỈNH SỬA: '\!' còn thiếu
-cmin
là "thay đổi trạng thái", -mmin
là "thay đổi dữ liệu". Bạn có thể muốn-mmin
find
có 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
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!