Bagaimana cara membuat daftar file yang lebih lama dari satu hari dengan "2015" dalam nama file?

11

Saya ingin membuat daftar semua file log yang bukan milik hari ini dan hanya file yang berisi 2015nama mereka.

Ini adalah perintah yang saya coba:

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

Output dari keduanya tidak ada apa-apanya, tetapi masih ada file di sana. Ada yang salah dengan perintah ini, dan saya tidak mendapatkan apa. Bantuan apa pun akan dihargai.

rɑːdʒɑ
sumber
Bagian ini findterlihat bagus untuk saya, tetapi saya juga punya masalah dengan -execparameternya. Saya juga tidak bisa membuatnya bekerja. (Saya mencoba untuk memindahkan semua file jpg dari satu folder ke direktori induknya melalui itu - dan akhirnya melakukannya secara manual ...)
Byte Commander
@steeldriver Saya pikir itu benar-benar apa yang salah di sini, karena jika ada file dalam direktori saat ini dengan 2015nama mereka (kelemahan jelas lainnya dari jalan perintah tertulis) saya menduga akan ada beberapa jenis output. Jadi, Anda mungkin ingin memposting jawaban tentang itu.
Eliah Kagan

Jawaban:

18

Perintah find . -name '*2015*' -mmin +1440 -lsmungkin akan melakukan apa yang Anda inginkan. Lihat di bawah untuk detailnya.

Perintah pertama Anda -name 2015. Itu tidak berfungsi karena hanya menemukan file yang namanya persis 2015 , tanpa karakter lain di dalamnya.

Perintah kedua Anda find . -name *2015* -mtime +1 -exec ls -ltrh {} \;,, mungkin gagal karena beberapa alasan:

1.* Karakter yang tidak dikutip diperluas oleh shell, lalu diteruskan ke find.

Jika ada file yang secara langsung terkandung dalam direktori saat ini ( file yang Anda gunakan saat menjalankan find ...perintah itu) yang namanya berisi 2015(dan tidak dimulai dengan a .), maka shell diperluas *2015*ke daftar nama-nama file tersebut, kemudian diteruskan daftar itu sebagai argumen untuk find. Ini bukan yang Anda inginkan - sebagai gantinya, Anda ingin menyampaikan *2015*secara harfiah sebagai argumen untuk ditemukan, sehingga find, dan bukan shell, dapat menemukan file mana yang cocok dengannya.

Untuk memperbaiki masalah itu, kutip *2015*. Ada tiga cara umum untuk melakukannya:

  • '*2015*'(yaitu, find . -name '*2015*' -mtime +1 -exec ls -ltrh {} \;)
  • "*2015*"(yaitu, find . -name "*2015*" -mtime +1 -exec ls -ltrh {} \;)
  • \*2015\*(yaitu, find . -name \*2015\* -mtime +1 -exec ls -ltrh {} \;)

Saya sarankan menulis itu dengan tanda kutip tunggal sebagai '*2015*', karena:

Tetapi dalam hal ini tidak terlalu penting. 'dan "keduanya memperlakukan *hal yang sama dan ungkapannya tidak cukup rumit untuk \dikutip sehingga sulit untuk dipahami.

2. -mtime +1hanya memilih file yang dimodifikasi dua hari atau lebih yang lalu.

Seperti man findkata:

       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.

Misalkan file diubah 47 jam yang lalu. Untuk mengetahui berapa banyak 24 jam periode yaitu, findputaran bawah : itu adalah satu periode 24 jam yang lalu. Tetapi -mtime +1hanya mencocokkan file yang waktu modifikasi ketat lebih dari satu periode 24 jam yang lalu. Dengan demikian file dari kemarin tidak cocok.

Lihat Mengapa menemukan -mtime +1 hanya mengembalikan file yang lebih tua dari 2 hari? untuk informasi lebih lanjut, seperti yang disarankan oleh steeldriver .

Untuk menemukan file yang terakhir dimodifikasi kapan saja lebih dari 24 jam yang lalu , saya sarankan menetapkannya 1440 menit yang lalu dengan -mmin +1440:

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

Beberapa pembaca mungkin bertanya-tanya mengapa saya tidak mengutip {}. Beberapa orang mengutip {}untuk mengingatkan manusia bahwa itu bukan ekspresi untuk ekspansi penjepit . Kerang bergaya Bourne (seperti bash ) tidak perlu {}dikutip di dalamnya. Mungkin beberapa shell non-Bourne-style memang memperlakukannya secara khusus; mungkin itulah sebabnya beberapa pengguna mengutipnya. Tetapi ada juga kesalahpahaman yang kadang-kadang harus dikutip {}sehingga -execmenangani nama file dengan spasi dengan benar. Itu salah: dengan {}atau '{}', findmendapatkan argumen yang sama , ketika shell menghapus tanda kutip sebelum diteruskan '{}'kefind. Untuk mengatasi kesalahpahaman ini, saya tidak mengutip {}, tetapi ini masalah gaya - jika Anda lebih suka {}mendokumentasikan bagaimana shell tidak memperlakukan {dan }khususnya, itu baik-baik saja.

Saya sarankan Anda juga baik mengubah Anda lsperintah, atau (seperti Muru telah menyarankan ) menggantinya dengan find's -lstindakan. ls -ltrhmungkin tidak melakukan apa yang Anda inginkan karena dijalankan secara terpisah untuk setiap file yang ditemukan sehingga flag -tdan -r, yang menentukan penyortiran, tidak relevan.

Meskipun output akan diformat sedikit berbeda dari dengan ls -l, menggunakan -lslebih sederhana dan lebih mudah.

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

Atau jika Anda memutuskan untuk benar-benar hanya perlu mencantumkan nama file (termasuk jalurnya, relatif terhadap .), Anda dapat dengan mudah menentukan tidak ada tindakan, yang menyebabkan -printtindakan default digunakan:

find . -name '*2015*' -mmin +1440
Eliah Kagan
sumber
1
Jawaban menyeluruh yang bagus! setidaknya dengan GNU find, ada juga newerXYsintaksis, yang menerima argumen kalender mis -newermt 'yesterday'dan! -newermt 'yesterday'
steeldriver
Kamu tahu apa ? Anda luar biasa. @ Eliah Kagan
rɑːdʒɑ
Terima kasih Stell Driver, itu informasi yang sangat bagus dari tautan untuk mengetahui. Tetapi dalam kasus saya karena ini adalah log aplikasi dari file aplikasi lama tidak bisa dimodifikasi. Terima kasih lagi
rɑːdɑː
2

Mengutip ekspresi dan saya sarankan Anda mengutip tanda kurung juga

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

atau

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

Anda tidak perlu meneruskan file yang Anda temukan ke ls

find . -name "*2015*" -mtime +1
Harimau kumbang
sumber
Mungkin membatasi penggunaan -type f? Dan jika lsharus digunakan, sarankan menggunakan -ls.
muru
1
tentu, semua saran bagus. Saya tidak yakin apa yang diinginkan OP dan saya percaya sumber masalahnya adalah kurangnya tanda kutip di sekitar pola pencarian "-nama".
Panther
2

Di zsh , Anda dapat menggunakan kualifikasi glob (ini adalah fitur zsh yang unik, tidak tersedia di shell lain seperti bash).

ls -ltr *2015*(m+1)

Ini hanya mencantumkan file dalam direktori saat ini; untuk menelusuri direktori secara rekursif , gunakan

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

Dengan find, -name 2015hanya menemukan file yang namanya persis 2015. -name *2015*hanya berfungsi jika tidak ada file yang namanya berisi 2015dalam direktori saat ini, karena shell memperluas pola *2015*sebelum finddipanggil. Anda perlu mengutip polanya:

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

Perhatikan bahwa keduanya find -mtime +1dan zsh's *(m+1)menemukan file yang berusia setidaknya 48 jam , bukan file yang lebih tua dari hari ini. Tanda plus berarti "lebih dari" dan jumlah hari dibulatkan. Untuk menemukan file yang berusia minimal 24 jam, gunakan -mtime +0atau (m+0).

Jika Anda ingin menemukan file yang terakhir dimodifikasi kemarin atau sebelumnya , Anda dapat menggunakan finddengan -newermtpredikat :

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

Tidak ada cara yang benar-benar nyaman untuk melakukan tes ini di zsh.

Gilles 'SANGAT berhenti menjadi jahat'
sumber