Kombinasi dari find
dan ls
bekerja dengan baik untuk
- nama file tanpa baris baru
- jumlah file tidak terlalu besar
- nama file tidak terlalu panjang
Solusinya:
find . -name "my-pattern" -print0 |
xargs -r -0 ls -1 -t |
head -1
Mari kita uraikan:
Dengan find
kami dapat mencocokkan semua file menarik seperti ini:
find . -name "my-pattern" ...
lalu gunakan -print0
kita dapat meneruskan semua nama file dengan aman ke ls
seperti ini:
find . -name "my-pattern" -print0 | xargs -r -0 ls -1 -t
tambahan find
parameter dan pola penelusuran dapat ditambahkan di sini
find . -name "my-pattern" ... -print0 | xargs -r -0 ls -1 -t
ls -t
akan mengurutkan file berdasarkan waktu modifikasi (terbaru dulu) dan mencetaknya satu per satu. Anda dapat menggunakan -c
untuk mengurutkan berdasarkan waktu pembuatan. Catatan :ini akan terputus dengan nama file yang berisi baris baru.
Terakhir head -1
memberi kita file pertama dalam daftar yang diurutkan.
Catatan: xargs
gunakan batasan sistem untuk ukuran daftar argumen. Jika ukuran ini melebihi, xargs
akan memanggil ls
beberapa kali. Ini akan merusak penyortiran dan mungkin juga hasil akhir. Jalankan
xargs --show-limits
untuk memeriksa batasan pada sistem Anda.
Catatan 2: gunakan find . -maxdepth 1 -name "my-pattern" -print0
jika Anda tidak ingin mencari file melalui subfolder.
Catatan 3: Seperti yang ditunjukkan oleh @starfry - -r
argumen untuk xargs
mencegah panggilan ls -1 -t
, jika tidak ada file yang cocok dengan find
. Terima kasih atas sarannya.
ls
perintah memiliki parameter -t
untuk mengurutkan berdasarkan waktu. Anda kemudian dapat mengambil yang pertama (terbaru) dengan head -1
.
ls -t b2* | head -1
Tapi hati-hati:Mengapa Anda tidak harus mengurai output dari ls
Pendapat pribadi saya:parsing ls
hanya berbahaya jika nama file dapat berisi karakter lucu seperti spasi atau baris baru. Jika Anda dapat menjamin bahwa nama file tidak akan mengandung karakter lucu maka parsing ls
cukup aman.
Jika Anda sedang mengembangkan skrip yang dimaksudkan untuk dijalankan oleh banyak orang di banyak sistem dalam berbagai situasi, maka saya sangat menyarankan untuk tidak mengurai ls
.
Berikut ini cara melakukannya dengan "benar":Bagaimana cara menemukan file terbaru (terbaru, terlama, terlama) di direktori?
unset -v latest
for file in "$dir"/*; do
[[ $file -nt $latest ]] && latest=$file
done
Ini adalah implementasi yang mungkin dari fungsi Bash yang diperlukan:
# Print the newest file, if any, matching the given pattern
# Example usage:
# newest_matching_file 'b2*'
# WARNING: Files whose names begin with a dot will not be checked
function newest_matching_file
{
# Use ${1-} instead of $1 in case 'nounset' is set
local -r glob_pattern=${1-}
if (( $# != 1 )) ; then
echo 'usage: newest_matching_file GLOB_PATTERN' >&2
return 1
fi
# To avoid printing garbage if no files match the pattern, set
# 'nullglob' if necessary
local -i need_to_unset_nullglob=0
if [[ ":$BASHOPTS:" != *:nullglob:* ]] ; then
shopt -s nullglob
need_to_unset_nullglob=1
fi
newest_file=
for file in $glob_pattern ; do
[[ -z $newest_file || $file -nt $newest_file ]] \
&& newest_file=$file
done
# To avoid unexpected behaviour elsewhere, unset nullglob if it was
# set by this function
(( need_to_unset_nullglob )) && shopt -u nullglob
# Use printf instead of echo in case the file name begins with '-'
[[ -n $newest_file ]] && printf '%s\n' "$newest_file"
return 0
}
Itu hanya menggunakan bawaan Bash, dan harus menangani file yang namanya berisi baris baru atau karakter tidak biasa lainnya.