Làm cách nào để liệt kê các tập tin cũ hơn một ngày với tên tệp 2015 2015 trong tên tệp?


11

Tôi muốn liệt kê tất cả các tệp nhật ký không thuộc về ngày hôm nay và chỉ các tệp có 2015trong tên của chúng.

Đây là những lệnh tôi đã thử:

find . -name 2015 -mtime +1 -exec  ls -ltrh  {} \;
find . -name *2015* -mtime +1 -exec  ls -ltrh  {} \;

Đầu ra từ cả hai không có gì, nhưng vẫn có các tập tin ở đó. Có gì đó không ổn với các lệnh này và tôi không nhận được gì. Bất kỳ trợ giúp sẽ được đánh giá cao.


Phần này có findvẻ tốt với tôi, nhưng tôi cũng gặp vấn đề với -exectham số. Tôi cũng không thể làm việc đó được. (Tôi đã cố gắng để di chuyển tất cả các file jpg từ một thư mục vào thư mục mẹ của nó qua nó - và kết thúc làm việc đó bằng tay ...)
Byte Commander


@steel ấn Tôi nghĩ rằng đó thực sự là những gì sai ở đây, vì nếu có các tệp trong thư mục hiện tại có 2015tên của họ (thiếu sót rõ ràng khác về cách viết lệnh) Tôi nghi ngờ sẽ có một loại đầu ra. Vì vậy, bạn có thể muốn gửi một câu trả lời về điều đó.
Eliah Kagan

Câu trả lời:


18

Lệnh find . -name '*2015*' -mmin +1440 -lscó thể sẽ làm những gì bạn muốn. Xem bên dưới để biết chi tiết.

Lệnh đầu tiên của bạn đã có -name 2015. Nó không hoạt động vì nó chỉ tìm thấy các tệp có tên chính xác 2015 , không có ký tự nào khác trong đó.

Lệnh thứ hai của bạn find . -name *2015* -mtime +1 -exec ls -ltrh {} \;, có thể đã thất bại vì một vài lý do:

1. Các *ký tự không trích dẫn được mở rộng bằng shell, sau đó được chuyển sang find.

Nếu có bất kỳ tệp nào được chứa trực tiếp trong thư mục hiện tại ( tệp bạn đang chạy khi bạn chạy find ...lệnh đó ) có tên chứa 2015(và không bắt đầu bằng a .), thì trình bao mở rộng *2015*thành một danh sách các tên tệp đó, sau đó được chuyển danh sách đó là đối số để find. Đây không phải là những gì bạn muốn - thay vào đó, bạn muốn vượt qua theo *2015*nghĩa đen như một đối số để tìm, để find, và không phải là vỏ, có thể tìm thấy các tệp phù hợp với nó.

Để khắc phục vấn đề đó, trích dẫn *2015*. Có ba cách phổ biến để làm điều đó:

  • '*2015*'(tức là find . -name '*2015*' -mtime +1 -exec ls -ltrh {} \;)
  • "*2015*"(tức là find . -name "*2015*" -mtime +1 -exec ls -ltrh {} \;)
  • \*2015\*(tức là find . -name \*2015\* -mtime +1 -exec ls -ltrh {} \;)

Tôi đề nghị viết nó với dấu ngoặc đơn'*2015*', bởi vì:

Nhưng trong trường hợp này nó không thực sự quan trọng. '"cả hai đều đối xử *như nhau và biểu thức không đủ phức tạp để \trích dẫn để làm cho nó khó hiểu.

2. -mtime +1chỉ chọn các tệp được sửa đổi hai hoặc nhiều ngày trước.

Như man findnói:

       Numeric arguments can be specified as

       +n     for greater than n,

       -n     for less than n,

       n      for exactly n.
       -mtime n
              File's data was last modified n*24 hours ago.  See the  comments
              for -atime to understand how rounding affects the interpretation
              of file modification times.
       -atime n
              File was last accessed n*24 hours ago.  When  find  figures  out
              how  many  24-hour  periods  ago the file was last accessed, any
              fractional part is ignored, so to match -atime +1, a file has to
              have been accessed at least two days ago.

Giả sử một tập tin đã được sửa đổi 47 giờ trước. Để tìm hiểu có bao nhiêu khoảng thời gian 24 giờ, làm findtròn xuống : đó là một khoảng thời gian 24 giờ trước. Nhưng -mtime +1chỉ khớp với các tệp có thời gian sửa đổi nghiêm ngặt hơn một khoảng thời gian 24 giờ trước. Do đó, các tập tin từ ngày hôm qua không được khớp.

Xem Tại sao find -mtime +1 chỉ trả về các tệp cũ hơn 2 ngày? để biết thêm thông tin, theo đề xuất của thép .

Để tìm các tệp được sửa đổi lần cuối bất cứ lúc nào hơn 24 giờ trước , tôi đề nghị thay vì quy định nó là 1440 phút trước với -mmin +1440:

find . -name '*2015*' -mmin +1440 -exec ls -ltrh {} \;

Một số độc giả có thể tự hỏi tại sao tôi không trích dẫn {}. Một số người trích dẫn {}để nhắc nhở con người rằng đó không phải là một biểu hiện cho việc mở rộng niềng răng . Các vỏ kiểu Bourne (như bash ) không yêu cầu {}không có gì bên trong để được trích dẫn. Có thể một số vỏ không phải kiểu Bourne đặc biệt đối xử với nó; đó có thể là lý do tại sao một số người dùng trích dẫn nó. Nhưng cũng có một quan niệm sai lầm rằng đôi khi người ta phải trích dẫn {}để -execxử lý tên tệp với khoảng trắng một cách chính xác. Điều đó là sai: với {}hoặc '{}', findcùng các đối số, vì trình bao loại bỏ các dấu ngoặc kép trước khi chuyển '{}'đếnfind. Để chống lại quan niệm sai lầm này, tôi không trích dẫn {}, nhưng đó là vấn đề về phong cách - nếu bạn muốn {}ghi lại cách thức vỏ không xử lý {}đặc biệt, điều đó tốt.

Tôi khuyên bạn nên bạn cũng có thể thay đổi bạn lslệnh, hoặc (như muru đã gợi ý ) thay thế bằng find's -lshành động. ls -ltrhcó thể không thực hiện những gì bạn dự định vì nó được chạy riêng cho từng tệp được tìm thấy và do đó, -tvà các -rcờ, trong đó chỉ định sắp xếp, không liên quan.

Mặc dù đầu ra sẽ được định dạng khác một chút so với ls -l, nhưng việc sử dụng -lsđơn giản và dễ dàng hơn.

find . -name '*2015*' -mmin +1440 -ls

Hoặc nếu bạn quyết định bạn thực sự chỉ cần liệt kê tên của tệp (bao gồm cả đường dẫn của chúng, liên quan đến .), bạn chỉ cần chỉ định không có hành động, khiến -printhành động mặc định được sử dụng:

find . -name '*2015*' -mmin +1440

1
Đẹp trả lời thấu đáo! ít nhất là với GNU find, cũng có newerXYcú pháp chấp nhận các đối số lịch, ví dụ -newermt 'yesterday'! -newermt 'yesterday'
Steeldo

Bạn biết gì ? Bạn thật tuyệt vời. @ Eliah Kagan
rɑːdʒɑ

Cảm ơn stell driver, đó là thông tin rất tốt từ liên kết để biết. Nhưng trong trường hợp của tôi vì nó là nhật ký ứng dụng từ các tệp cũ của ứng dụng không có cách nào để sửa đổi. Cảm ơn bạn một lần nữa
rdʒɑ

2

Trích dẫn biểu thức và tôi đề nghị bạn cũng trích dẫn dấu ngoặc

find . -name "2015" -mtime +1 -exec  ls -ltrh  '{}' \;

hoặc là

find . -name "*2015*" -mtime +1 -exec  ls -ltrh  '{}' \;

bạn không cần phải chuyển các tập tin bạn tìm đến ls

find . -name "*2015*" -mtime +1

Có thể hạn chế sử dụng -type f? Và nếu lsphải được sử dụng, đề nghị sử dụng -ls.
muru

1
chắc chắn, tất cả các đề xuất tốt. Tôi không chắc chắn OP muốn gì và tôi tin rằng nguồn gốc của vấn đề là thiếu dấu ngoặc kép xung quanh mẫu tìm kiếm "-name".
Panther

2

Trong zsh , bạn có thể sử dụng vòng loại toàn cầu (đây là một tính năng zsh duy nhất, không có sẵn trong các shell khác như bash).

ls -ltr *2015*(m+1)

Điều này chỉ liệt kê các tập tin trong thư mục hiện tại; để truy cập các thư mục đệ quy , sử dụng

ls -ltr **/*2015*(m+1)

Với find, -name 2015chỉ tìm thấy các tập tin có tên chính xác 2015. -name *2015*chỉ hoạt động nếu không có tệp nào có tên chứa 2015trong thư mục hiện tại, vì shell mở rộng mẫu *2015*trước khi findđược gọi. Bạn cần trích dẫn mẫu:

find -name '*2015*' -mtime +1 …

Lưu ý rằng cả hai find -mtime +1và zsh đều *(m+1)tìm thấy các tệp ít nhất 48 giờ , không phải các tệp cũ hơn ngày hôm nay. Dấu cộng có nghĩa là nghiêm khắc hơn nhiều so với nhóm và số ngày được làm tròn xuống. Để tìm các tệp ít nhất 24 giờ, hãy sử dụng -mtime +0hoặc (m+0).

Nếu bạn muốn tìm các tệp được sửa đổi lần cuối ngày hôm qua hoặc trước đó , bạn có thể sử dụng findvới -newermtvị từ :

find -name '*2015*' ! -newermt 'today 0:00' …

Không có cách nào thực sự thuận tiện để thực hiện bài kiểm tra này trong zsh.

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.