Cách di chuyển tệp dựa trên Năm


14

Tôi cần di chuyển các tập tin dựa trên một năm. Tôi đã sử dụng findlệnh

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

nhưng để lệnh này thực thi thành công tôi cần biết chính xác mtimebây giờ 470 chỉ là phỏng đoán. Có nghĩa là nếu tôi có thể cung cấp cho năm 2012, nó cung cấp cho tôi các tệp chỉ liên quan đến năm 2012.

Vì vậy, tôi cần lời khuyên về cách

Tìm tệp dựa trên năm, ví dụ 2012 và chuyển chúng sang thư mục khác.

OS release 5.2

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

Liệu nó có ý nghĩa để sử dụng -exec ls ... \;thay vì -exec ... +? Là bạn thấy quá cũ cho điều đó? Trong trường hợp find ... -print0 | xargs -0 ls...đó sẽ nhanh hơn nhiều.
Hauke ​​Laging

Tôi muốn những câu hỏi này (và câu trả lời) liên quan đến coreutils sẽ thường xuyên chỉ định liệu chúng ta đang xử lý các tiện ích GNU hay BSD (hoặc khác).
mê cung

Câu trả lời:


37

Bạn muốn sử dụng -newermttùy chọn cho find:

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

để có được tất cả các tập tin với thời gian sửa đổi trong năm 2012.

Nếu phát hiện của bạn không hỗ trợ, -newermtbạn cũng có thể thực hiện các thao tác sau để ngăn sử dụng tính toán bù:

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 cờ không khả dụng trong lệnh Tìm
OmiPenguin

Đó phải là một phiên bản cũ của tìm thấy rằng RHEL của bạn đi kèm? Tôi sẽ cung cấp một giải pháp thay thế trong câu trả lời cho điều đó
Anthon

Có cái này là 5.2
OmiPenguin

Tôi coi đó là bản sửa đổi của RHEL, không phải find(tôi đã tìm thấy phiên bản 4.4.2)
Anthon

1
Công tắc newermt không xuất hiện trong tìm kiếm cho đến các phiên bản sau v4.3.3, gnu.org/software/findutils/manual/html_mono/find.html .
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 không có ý nghĩa gì.


1
-exec ls -lcó ý nghĩa hơn, và thậm chí nhiều hơn trong khi thử nghiệm.
một CVn

@ MichaelKjorling findcó thể in mọi thứ lscó thể. OK, với một ngoại lệ: thoát / trích dẫn các ký tự khó chịu. Nhưng nói chung, đầu ra của findcó thể được sắp xếp trực tiếp. Các cuộc gọi vô dụng của ls không làm cho toàn bộ mọi thứ nhanh hơn.
Hauke ​​Laging

Tôi rất thường sử dụng một cái gì đó khá giống nhau (mặc dù cá nhân tôi thích -printhoặc có thể -ls ) trong khi thử nghiệm. Ưu điểm của việc sử dụng -exec ls {}là nó đã thực thi một cái gì đó bên ngoài để tìm . Vì vậy, khi bạn chuyển từ lssang mv, những thay đổi thực tế là tối thiểu.
một CVn

3

Theo trang người đàn ông, đối số đến -mtime là số ngày bạn đang tìm kiếm. Bạn có thể sử dụng date +%jđể tìm số ngày kể từ ngày 1 tháng 1 của năm hiện tại.


2
Cách tốt đẹp. Rất "nitpicky": -mtime -1: là bất kỳ tệp nào trong 24 giờ qua. Không chỉ các tập tin từ ngày hôm qua (hoặc hôm nay). Vì vậy, cũng sẽ có một chút "chồng chéo": nếu bạn xác định đã 120 ngày kể từ năm 2012 và hôm nay là 15:45 khi bạn khởi chạy tập lệnh, cuối cùng bạn sẽ chọn các tệp cho đến ngày 31/1245 ( và không phải là những người cuối cùng của ngày hôm đó) ... Bạn có thể sử dụng: nb_day - 1, và sau đó "loại bỏ" những người hẹn hò từ năm 2013 (những người có thể tìm thấy bởi một ls -l | grep -v, NHƯNG đầu ra khác nhau nếu chúng chỉ 1 ngày tuổi ... rất nhiều cạm bẫy ...)
Olivier Dulac

Bạn muốn sử dụng -daystarttùy chọn nếu bạn sẽ làm việc với -mtime. Nếu không, bạn sẽ gặp vấn đề với các tệp vào khoảng đầu và cuối năm dù bạn xoay theo cách nào trừ khi bạn chạy chính xác vào lúc nửa đêm. Bạn có thể thực hiện bù trừ chính xác -mminhơn so với -mtimenếu bạn có thể tìm thấy số phút kể từ năm mới một cách dễ dàng. Nhưng vấn đề tương tự tồn tại với điều đó cũng như với -mtime, chỉ với ít tệp hơn (những phút đó vào khoảng nửa đêm năm mới).
Anthon

1
Vâng, đọc lại trang người đàn ông Tôi đang thấy cách nó chia nhỏ hàng giờ nên làm một việc đơn giản find -mtime $("date -+%j")có lẽ sẽ không mang lại cho OP những gì họ sẽ làm. Tôi sẽ để lại cho hậu thế mặc dù điều này có vẻ như là một điểm mù có thể xảy ra đối với mọi người.
Bratchley

2

Bạn có thể thử sử dụng kết hợp với các lệnh statvà / hoặc datenhư trong các lớp lót sau:

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

Trong cả hai trường hợp, cách tiếp cận là sử dụng datelệnh để trích xuất năm từ thời gian sửa đổi cuối cùng của mỗi tệp và sau đó để xây dựng một đường dẫn với năm nay. Lệnh mkdir -psẽ tạo đường dẫn này nếu nó chưa tồn tại. Tất nhiên bạn có thể sử dụng một số findtùy chọn khác để tinh chỉnh tìm kiếm của bạn.


1

Nếu bạn làm điều này từ thư mục làm việc, bạn có thể làm điều này thay vào đó:

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

Điều này đơn giản hóa mọi thứ đáng kể và không gây ra bất kỳ sự chồng chéo nào. Nhưng nó cũng giả định rằng các tệp này cũ hơn 6 tháng tuổi và lssẽ in năm thay vì thời gian chính xác.

Đối với các tệp mới hơn 6 tháng tuổi, bạn sẽ phải thay thế nó bằng tệp này:

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

hoặc một cái gì đó tương tự, tùy thuộc vào tháng. Nếu bạn muốn tạo danh sách các tháng để di chuyển tệp cho (hoặc nếu bạn muốn tạo danh sách trong nhiều năm), hãy làm điều này:

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
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.