Tampaknya ls
tidak mengurutkan file dengan benar saat melakukan panggilan rekursif:
ls -altR . | head -n 3
Bagaimana saya dapat menemukan file yang paling baru dimodifikasi dalam direktori (termasuk subdirektori)?
Tampaknya ls
tidak mengurutkan file dengan benar saat melakukan panggilan rekursif:
ls -altR . | head -n 3
Bagaimana saya dapat menemukan file yang paling baru dimodifikasi dalam direktori (termasuk subdirektori)?
Jawaban:
find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "
Untuk pohon besar, mungkin sulit untuk sort
menyimpan semuanya dalam ingatan.
%T@
memberi Anda waktu modifikasi seperti cap waktu unix, sort -n
mengurutkan secara numerik, tail -1
mengambil baris terakhir (cap waktu tertinggi), cut -f2 -d" "
memotong bidang pertama (timestamp) dari output.
Sunting: Sama seperti -printf
mungkin hanya GNU, penggunaan tambahan stat -c
juga. Meskipun dimungkinkan untuk melakukan hal yang sama pada BSD, opsi untuk memformat berbeda ( -f "%m %N"
sepertinya)
Dan saya merindukan bagian dari jamak; jika Anda menginginkan lebih dari file terbaru, cukup tambahkan argumen ekor.
sort -rn | head -3
bukan sort -n | tail -3
. Satu versi memberikan file dari yang terlama ke yang terbaru, sementara yang lain beralih dari yang terbaru ke terlama.
sort
akan membuat file sementara (dalam /tmp
) sesuai kebutuhan, jadi saya tidak berpikir itu masalah.
-printf '%T@ %Tb %Td %TY %p\n'
akan memberi Anda cap tanggal (jika perlu) (mirip dengan ls
)
find . -type f -printf '%TF %TT %p\n' | sort | tail -1
Menindaklanjuti jawaban @ plundra , inilah versi BSD dan OS X:
find . -type f -print0 | xargs -0 stat -f "%m %N" |
sort -rn | head -1 | cut -f2- -d" "
find
mendukung +
bukan \;
? Karena itu melakukan hal yang sama (melewati beberapa file sebagai parameter), tanpa -print0 | xargs -0
pipa.
head -1
kehead -5
Alih-alih mengurutkan hasil dan hanya menyimpan hasil modifikasi terakhir, Anda dapat menggunakan awk untuk mencetak hanya hasil dengan waktu modifikasi terbesar (dalam waktu unix):
find . -type f -printf "%T@\0%p\0" | awk '
{
if ($0>max) {
max=$0;
getline mostrecent
} else
getline
}
END{print mostrecent}' RS='\0'
Ini harus menjadi cara yang lebih cepat untuk menyelesaikan masalah Anda jika jumlah file cukup besar.
Saya telah menggunakan karakter NUL (yaitu '\ 0') karena, secara teoritis, nama file dapat berisi karakter apa pun (termasuk spasi dan baris baru) tetapi itu.
Jika Anda tidak memiliki nama pathologis dalam sistem Anda, Anda dapat menggunakan karakter baris baru juga:
find . -type f -printf "%T@\n%p\n" | awk '
{
if ($0>max) {
max=$0;
getline mostrecent
} else
getline
}
END{print mostrecent}' RS='\n'
Selain itu, ini berfungsi di mawk juga.
mawk
, alternatif standar Debian.
Saya mengalami kesulitan untuk menemukan file yang dimodifikasi terakhir di bawah Solaris 10. Tidak find
ada printf
opsi dan stat
tidak tersedia. Saya menemukan solusi berikut yang bekerja dengan baik untuk saya:
find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7 }' | sort | tail -1
Untuk menampilkan nama file juga gunakan
find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7," ",$9 }' | sort | tail -1
Penjelasan
find . -type f
menemukan dan mendaftar semua filesed 's/.*/"&"/'
membungkus pathname dalam tanda kutip untuk menangani spasi putihxargs ls -E
mengirimkan jalur yang dikutip ke ls
, -E
opsi memastikan bahwa stempel waktu penuh (format tahun-bulan-hari-jam-menit-detik-nanoseconds ) dikembalikanawk '{ print $6," ",$7 }'
ekstrak hanya tanggal dan waktuawk '{ print $6," ",$7," ",$9 }'
ekstrak tanggal, waktu, dan nama filesort
mengembalikan file yang diurutkan berdasarkan tanggaltail -1
hanya mengembalikan file yang terakhir dimodifikasiIni tampaknya berfungsi dengan baik, bahkan dengan subdirektori:
find . -type f | xargs ls -ltr | tail -n 1
Jika terlalu banyak file, perbaiki temuan.
-l
pilihan untuk ls
tampaknya tidak perlu. Hanya -tr
tampaknya cukup.
find . -type f -print0 | xargs -0 ls -ltr | tail -n 1
Memperlihatkan file terbaru dengan stempel waktu yang dapat dibaca manusia:
find . -type f -printf '%TY-%Tm-%Td %TH:%TM: %Tz %p\n'| sort -n | tail -n1
Hasilnya terlihat seperti ini:
2015-10-06 11:30: +0200 ./foo/bar.txt
Untuk menampilkan lebih banyak file, ganti -n1
dengan nomor yang lebih tinggi
Saya menggunakan sesuatu yang serupa sepanjang waktu, serta daftar top-k dari file yang paling baru dimodifikasi. Untuk pohon direktori besar, bisa jadi lebih cepat untuk menghindari penyortiran . Dalam hal hanya file top-1 yang paling baru dimodifikasi:
find . -type f -printf '%T@ %p\n' | perl -ne '@a=split(/\s+/, $_, 2); ($t,$f)=@a if $a[0]>$t; print $f if eof()'
Pada direktori yang berisi 1,7 juta file, saya mendapatkan yang terbaru dalam 3.4s, kecepatan 7.5x terhadap solusi 25.5s menggunakan sort.
lastfile
) dan kemudian Anda dapat melakukan apa pun yang Anda suka dengan hasilnya, seperti ls -l $(lastfile .)
, atau open $(lastfile .)
(pada Mac), dll.
Di Ubuntu 13, yang berikut melakukannya, mungkin sedikit lebih cepat, karena membalikkan pengurutan dan menggunakan 'head' alih-alih 'tail', mengurangi pekerjaan. Untuk menampilkan 11 file terbaru di pohon:
Temukan . -type f -printf '% T @% p \ n' | sort -n -r | kepala -11 | cut -f2- -d "" | sed -e's, ^. / ,, '| xargs ls -U -l
Ini memberikan daftar lengkap ls tanpa menyortir ulang dan menghilangkan './' yang mengganggu menempatkan 'pada setiap nama file.
Atau, sebagai fungsi bash:
treecent () {
local numl
if [[ 0 -eq $# ]] ; then
numl=11 # Or whatever default you want.
else
numl=$1
fi
find . -type f -printf '%T@ %p\n' | sort -n -r | head -${numl} | cut -f2- -d" " | sed -e 's,^\./,,' | xargs ls -U -l
}
Namun, sebagian besar pekerjaan dilakukan oleh solusi asli Plundra. Terima kasih, plundra.
Saya menghadapi masalah yang sama. Saya perlu menemukan file terbaru secara rekursif. menemukan butuh sekitar 50 menit untuk menemukan.
Berikut ini sedikit skrip untuk melakukannya lebih cepat:
#!/bin/sh
CURRENT_DIR='.'
zob () {
FILE=$(ls -Art1 ${CURRENT_DIR} | tail -n 1)
if [ ! -f ${FILE} ]; then
CURRENT_DIR="${CURRENT_DIR}/${FILE}"
zob
fi
echo $FILE
exit
}
zob
Ini adalah fungsi rekursif yang mendapatkan item yang dimodifikasi terbaru dari direktori. Jika item ini adalah direktori, fungsinya disebut secara rekursif dan mencari ke direktori ini, dll.
Saya menemukan yang berikut ini lebih pendek dan dengan output yang lebih dapat diartikan:
find . -type f -printf '%TF %TT %p\n' | sort | tail -1
Mengingat panjang tetap dari format data ISO standar, pengurutan lexicographical baik-baik saja dan kami tidak membutuhkan -n
opsi pada pengurutan.
Jika Anda ingin menghapus stempel waktu lagi, Anda dapat menggunakan:
find . -type f -printf '%TFT%TT %p\n' | sort | tail -1 | cut -f2- -d' '
Jika berjalan stat
pada setiap file satu per satu adalah memperlambat Anda dapat menggunakan xargs
untuk mempercepat beberapa hal:
find . -type f -print0 | xargs -0 stat -f "%m %N" | sort -n | tail -1 | cut -f2- -d" "
Ini secara rekursif mengubah waktu modifikasi dari semua direktori di direktori saat ini ke file terbaru di setiap direktori:
for dir in */; do find $dir -type f -printf '%T@ "%p"\n' | sort -n | tail -1 | cut -f2- -d" " | xargs -I {} touch -r {} $dir; done
Klien sederhana ini juga akan berfungsi:
ls -1t | head -1
Anda dapat mengubah -1 ke jumlah file yang ingin Anda daftarkan
Saya menemukan perintah di atas berguna, tetapi untuk kasus saya, saya perlu melihat tanggal dan waktu file juga saya punya masalah dengan beberapa file yang memiliki spasi dalam nama-nama. Inilah solusi kerja saya.
find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" " | sed 's/.*/"&"/' | xargs ls -l
$ find . -type f -not -path '*/\.*' -printf '%TY.%Tm.%Td %THh%TM %Ta %p\n' |sort -nr |head -n 10
Menangani spasi dalam nama file dengan baik - bukan berarti ini harus digunakan!
2017.01.25 18h23 Wed ./indenting/Shifting blocks visually.mht
2016.12.11 12h33 Sun ./tabs/Converting tabs to spaces.mht
2016.12.02 01h46 Fri ./advocacy/2016.Vim or Emacs - Which text editor do you prefer?.mht
2016.11.09 17h05 Wed ./Word count - Vim Tips Wiki.mht
Lebih find
berlimpah mengikuti tautan.
Untuk mencari file di / target_directory dan semua sub-direktorinya, yang telah dimodifikasi dalam 60 menit terakhir:
$ find /target_directory -type f -mmin -60
Untuk menemukan file yang paling baru dimodifikasi, diurutkan dalam urutan terbalik dari waktu pembaruan (yaitu, file yang paling baru diperbarui terlebih dahulu):
$ find /etc -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r
Saya lebih suka yang ini, lebih pendek:
find . -type f -print0|xargs -0 ls -drt|tail -n 1
Saya menulis paket pypi / github untuk pertanyaan ini karena saya memerlukan solusi juga.
https://github.com/bucknerns/logtail
Install:
pip install logtail
Penggunaan: ekor berganti file
logtail <log dir> [<glob match: default=*.log>]
Kegunaan2: Membuka file yang diubah terakhir di editor
editlatest <log dir> [<glob match: default=*.log>]