ค้นหาคำสั่งที่จะส่งคืนไฟล์ล่าสุดในไดเรกทอรี
ไม่เห็นพารามิเตอร์ จำกัด ถึงls
...
ls
หรือการใช้งานที่find
ไม่มี-print0
ปัญหาในการจัดการชื่อไฟล์ที่น่ารำคาญ มีประโยชน์เสมอที่จะกล่าวถึง: BashFAQ099ซึ่งให้คำตอบกับ POSIX สำหรับปัญหานี้
ค้นหาคำสั่งที่จะส่งคืนไฟล์ล่าสุดในไดเรกทอรี
ไม่เห็นพารามิเตอร์ จำกัด ถึงls
...
ls
หรือการใช้งานที่find
ไม่มี-print0
ปัญหาในการจัดการชื่อไฟล์ที่น่ารำคาญ มีประโยชน์เสมอที่จะกล่าวถึง: BashFAQ099ซึ่งให้คำตอบกับ POSIX สำหรับปัญหานี้
คำตอบ:
ls -Art | tail -n 1
ไม่หรูหรามาก แต่ใช้งานได้
ls
ไปยังท่อทั้งหมดtail
แล้วพิมพ์เฉพาะบรรทัดสุดท้าย IMHO มันจะดีกว่าที่จะเรียงลำดับจากน้อยไปมากและใช้head
แทนตามที่chaos
แนะนำ หลังจากการพิมพ์ส่วนหัวบรรทัดแรกหยุดทำงานดังนั้นการส่งบรรทัดถัดไป (จริง ๆ แล้วบล็อกถัดไป) จะเพิ่ม SIGPIPE และls
จะปิดเช่นกัน
ls -t | head -n1
คำสั่งนี้ให้ไฟล์ที่แก้ไขล่าสุดในไดเร็กทอรีการทำงานปัจจุบันจริง ๆ
ls -tl | head -n 1
และไม่จำเป็นต้องผลักทั้งตารางผ่านทางท่อในแบบที่ฉันทำ
ls -t *.png | head -n1
ls -Art | head -n1
หากคุณต้องการไฟล์ที่แก้ไขล่าสุดโดยเฉพาะ
นี่เป็นเวอร์ชันแบบเรียกซ้ำ (เช่นจะค้นหาไฟล์ที่อัพเดตล่าสุดในไดเรกทอรีหนึ่ง ๆ หรือไดเรกทอรีย่อยใด ๆ )
find $DIR -type f -printf "%T@ %p\n" | sort -n | cut -d' ' -f 2- | tail -n 1
แก้ไข: ใช้-f 2-
แทน-f 2
ตามที่เควินแนะนำ
find $DIR -type f -exec stat -lt "%Y-%m-%d" {} \+ | cut -d' ' -f6- | sort -n | tail -1
sort -nr
คุณสามารถใช้head -n 1
แทนtail -n 1
และปรับปรุงประสิทธิภาพได้เล็กน้อย ( แต่ถ้าคุณกำลังเรียงลำดับหา recursive รับบรรทัดแรกหรือสุดท้ายจะไม่เป็นส่วนหนึ่งช้า.)
find ./ -type f -printf "%T@ %p\n" -ls | sort -n | cut -d' ' -f 2- | tail -n 1 | xargs -r ls -lah
find $DIR -type f -exec stat -lt "%F %T" {} \+ | cut -d' ' -f6- | sort -n | tail -1
หมายเหตุเกี่ยวกับความน่าเชื่อถือ:
เนื่องจากอักขระขึ้นบรรทัดใหม่นั้นมีความถูกต้องเหมือนในชื่อไฟล์โซลูชันใด ๆ ที่อาศัยบรรทัดเช่นhead
/ tail
ตามตัวอักษรนั้นมีข้อบกพร่อง
ด้วย GNU ls
ตัวเลือกอื่นคือใช้--quoting-style=shell-always
ตัวเลือกและbash
อาร์เรย์:
eval "files=($(ls -t --quoting-style=shell-always))"
((${#files[@]} > 0)) && printf '%s\n' "${files[0]}"
(เพิ่ม-A
ตัวเลือกในls
หากคุณต้องการพิจารณาไฟล์ที่ซ่อนอยู่ด้วย)
หากคุณต้องการ จำกัด ไฟล์ปกติ (ไม่สนใจไดเรกทอรี, Fifos, อุปกรณ์, symlink, sockets ... ) คุณจะต้องหันไปใช้ GNU find
GNU
ด้วย bash 4.4 หรือใหม่กว่า (สำหรับreadarray -d
) และ GNU coreutils 8.25 หรือใหม่กว่า (สำหรับcut -z
):
readarray -t -d '' files < <(
LC_ALL=C find . -maxdepth 1 -type f ! -name '.*' -printf '%T@/%f\0' |
sort -rzn | cut -zd/ -f2)
((${#files[@]} > 0)) && printf '%s\n' "${files[0]}"
หรือเรียกซ้ำ:
readarray -t -d '' files < <(
LC_ALL=C find . -name . -o -name '.*' -prune -o -type f -printf '%T@%p\0' |
sort -rzn | cut -zd/ -f2-)
สิ่งที่ดีที่สุดที่นี่คือการใช้zsh
และโปรแกรมคัดเลือกแบบกลมแทนที่จะbash
หลีกเลี่ยงความยุ่งยากทั้งหมดนี้:
ไฟล์ปกติใหม่ล่าสุดในไดเรกทอรีปัจจุบัน:
printf '%s\n' *(.om[1])
รวมถึงรายการที่ซ่อนอยู่:
printf '%s\n' *(D.om[1])
ใหม่สุดที่สอง:
printf '%s\n' *(.om[2])
ตรวจสอบอายุไฟล์หลังจากความละเอียด symlink:
printf '%s\n' *(-.om[1])
ซ้ำ:
printf '%s\n' **/*(.om[1])
นอกจากนี้เมื่อcompinit
เปิดใช้งานระบบเสร็จสมบูรณ์ ( และร่วม)Ctrl+Xmจะกลายเป็นคอมไพเลอร์ที่ขยายเป็นไฟล์ใหม่ล่าสุด
ดังนั้น:
vi Ctrl+Xm
จะทำให้คุณแก้ไขไฟล์ใหม่ล่าสุด (คุณยังมีโอกาสได้เห็นไฟล์ก่อนกด Return )
vi Alt+2Ctrl+Xm
สำหรับไฟล์ใหม่ล่าสุดที่สอง
vi * .cCtrl+Xm
สำหรับใหม่ล่าสุด c
ไฟล์
vi * (.)Ctrl+Xm
สำหรับไฟล์ปกติใหม่ล่าสุด(ไม่ใช่ไดเรกทอรีหรือ Fifo / อุปกรณ์ ... ) และอื่น ๆ
zsh
เคล็ดลับ คุณสามารถให้ลิงค์ไปยังรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้ในเอกสาร zsh ได้ไหม?
info zsh qualifiers
ฉันใช้:
ls -ABrt1 --group-directories-first | tail -n1
มันให้ฉันแค่ชื่อไฟล์ไม่รวมโฟลเดอร์
ls -lAtr | tail -1
โซลูชันอื่นไม่รวมไฟล์ที่ขึ้นต้นด้วย '.'
ไม่รวมถึงไฟล์ที่เริ่มต้นด้วย
คำสั่งนี้จะรวมถึง'.'
และ'..'
ซึ่งอาจหรืออาจไม่ใช่สิ่งที่คุณต้องการ:
ls -latr | tail -1
Shorted Variant ตามคำตอบของ dmckee:
ls -t | head -1
-1
ไวยากรณ์ที่จะเลิกใช้มานานแล้วและ-n 1
ควรจะใช้
ฉันชอบ echo *(om[1])
( zsh
ไวยากรณ์) ตามที่เพิ่งให้ชื่อไฟล์และไม่ได้เรียกคำสั่งอื่น ๆ
โซลูชัน find / sort ใช้งานได้ดีจนกระทั่งจำนวนไฟล์มีขนาดใหญ่มาก (เช่นระบบไฟล์ทั้งหมด) ใช้ awk แทนเพื่อติดตามไฟล์ล่าสุด:
find $DIR -type f -printf "%T@ %p\n" |
awk '
BEGIN { recent = 0; file = "" }
{
if ($1 > recent)
{
recent = $1;
file = $0;
}
}
END { print file; }' |
sed 's/^[0-9]*\.[0-9]* //'
โดยส่วนตัวฉันชอบที่จะใช้bash
คำสั่งที่ไม่ได้มีให้ในตัวน้อยที่สุดเท่าที่จะทำได้ (เพื่อลดจำนวนส้อมและ exec syscalls ที่มีราคาแพง) หากต้องการจัดเรียงตามวันที่ls
จำเป็นต้องเรียกใช้ แต่การใช้head
ไม่จำเป็นจริงๆ ฉันใช้หนึ่งซับต่อไปนี้ (ใช้ได้กับระบบที่รองรับท่อชื่อ):
read newest < <(ls -t *.log)
หรือเพื่อรับชื่อไฟล์ที่เก่าที่สุด
read oldest < <(ls -rt *.log)
(คำนึงถึงช่องว่างระหว่างเครื่องหมาย '<' สองอัน!)
หากไฟล์ที่ซ่อนอยู่ยังต้องการ -Ag สามารถเพิ่ม
ฉันหวังว่านี่จะช่วยได้
ใช้ตัวเลือกแบบเรียกซ้ำ R .. คุณอาจถือว่านี่เป็นการปรับปรุงสำหรับคำตอบที่ดีที่นี่
ls -arRtlh | tail -50
ls -t -1 | sed '1q'
จะแสดงรายการที่แก้ไขล่าสุดในโฟลเดอร์ จับคู่กับgrep
เพื่อค้นหารายการล่าสุดด้วยคำหลัก
ls -t -1 | grep foo | sed '1q'
1
สำหรับบรรทัดแรกhead -n 1
เท่ากับคิวคืออะไร?
ซ้ำ:
find $1 -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head
ลองใช้คำสั่งง่ายๆนี้
ls -ltq <path> | head -n 1
หากคุณต้องการชื่อไฟล์ - แก้ไขล่าสุด path = /ab/cd/*.log
ถ้าคุณต้องการชื่อไดเรกทอรี - แก้ไขครั้งล่าสุด path = / ab / cd / * /
สมมติว่าคุณไม่สนใจไฟล์ที่ซ่อนที่เริ่มต้นด้วย .
ls -rt | tail -n 1
มิฉะนั้น
ls -Art | tail -n 1
ด้วย Bash builtins เท่านั้นติดตามBashFAQ / 003อย่างใกล้ชิด:
shopt -s nullglob
for f in * .*; do
[[ -d $f ]] && continue
[[ $f -nt $latest ]] && latest=$f
done
printf '%s\n' "$latest"
LS ทุกคน / แก้ปัญหาหางทำงานได้อย่างสมบูรณ์ดีสำหรับไฟล์ในไดเรกทอรี - ไดเรกทอรีย่อยละเลย
เพื่อที่จะรวมไฟล์ทั้งหมดในการค้นหาของคุณ (เรียกซ้ำ) คุณสามารถใช้ find ได้ gioele แนะนำให้เรียงลำดับผลลัพธ์การค้นหาที่จัดรูปแบบ แต่ระวังด้วย whitespaces (คำแนะนำของเขาใช้ไม่ได้กับ whitespaces)
สิ่งนี้ควรใช้กับชื่อไฟล์ทั้งหมด:
find $DIR -type f -printf "%T@ %p\n" | sort -n | sed -r 's/^[0-9.]+\s+//' | tail -n 1 | xargs -I{} ls -l "{}"
เรียงลำดับตามเวลาดูคนค้นหา:
%Ak File's last access time in the format specified by k, which is either `@' or a directive for the C `strftime' function. The possible values for k are listed below; some of them might not be available on all systems, due to differences in `strftime' between systems.
@ seconds since Jan. 1, 1970, 00:00 GMT, with fractional part.
%Ck File's last status change time in the format specified by k, which is the same as for %A.
%Tk File's last modification time in the format specified by k, which is the same as for %A.
ดังนั้นแทนที่%T
ด้วย%C
การจัดเรียงตามเวลา
find $DIR -type f -printf "%T@ %p\n" | sort -n | cut -d' ' -f 2- | tail -n 1
หรือมิฉะนั้นให้เก็บทั้งหมดยกเว้นฟิลด์แรก: find $DIR -type f -printf "%T@ %p\n" | sort -n | cut -d' ' -f 1 --complement | tail -n 1
การค้นหาไฟล์ล่าสุดในทุกไดเรกทอรีตามรูปแบบเช่นไดเรกทอรีย่อยของไดเรกทอรีทำงานที่มีชื่อลงท้ายด้วย "tmp" (ไม่คำนึงถึงขนาดตัวพิมพ์):
find . -iname \*tmp -type d -exec sh -c "ls -lArt {} | tail -n 1" \;
ls -Frt | grep "[^/]$" | tail -n 1
หากคุณต้องการรับไฟล์ที่มีการเปลี่ยนแปลงล่าสุดรวมถึงไดเรกทอรีย่อยใด ๆ คุณสามารถทำได้ด้วย oneliner ตัวน้อยนี้:
find . -type f -exec stat -c '%Y %n' {} \; | sort -nr | awk -v var="1" 'NR==1,NR==var {print $0}' | while read t f; do d=$(date -d @$t "+%b %d %T %Y"); echo "$d -- $f"; done
หากคุณต้องการทำสิ่งเดียวกันไม่ใช่สำหรับไฟล์ที่ถูกเปลี่ยน แต่สำหรับไฟล์ที่เข้าถึงคุณต้องเปลี่ยน
% Yพารามิเตอร์จากสถิติคำสั่งX% และคำสั่งของคุณสำหรับไฟล์ที่เข้าถึงล่าสุดมีลักษณะดังนี้:
find . -type f -exec stat -c '%X %n' {} \; | sort -nr | awk -v var="1" 'NR==1,NR==var {print $0}' | while read t f; do d=$(date -d @$t "+%b %d %T %Y"); echo "$d -- $f"; done
สำหรับทั้งคำสั่งคุณยังสามารถเปลี่ยนพารามิเตอร์var = "1"หากคุณต้องการแสดงรายการมากกว่าหนึ่งไฟล์
ฉันจำเป็นต้องทำเช่นกันและฉันพบคำสั่งเหล่านี้ งานเหล่านี้สำหรับฉัน:
หากคุณต้องการไฟล์ล่าสุดตามวันที่สร้างในโฟลเดอร์ (เวลาเข้าถึง):
ls -Aru | tail -n 1
และหากคุณต้องการไฟล์ล่าสุดที่มีการเปลี่ยนแปลงเนื้อหา (แก้ไขเวลา):
ls -Art | tail -n 1
watch -n1 'ls -Art | tail -n 1'
- แสดงไฟล์ล่าสุด