ดูเหมือนว่าls
จะไม่เรียงลำดับไฟล์อย่างถูกต้องเมื่อทำการโทรซ้ำ:
ls -altR . | head -n 3
ฉันจะค้นหาไฟล์ที่แก้ไขล่าสุดในไดเรกทอรี (รวมถึงไดเรกทอรีย่อย) ได้อย่างไร
ดูเหมือนว่าls
จะไม่เรียงลำดับไฟล์อย่างถูกต้องเมื่อทำการโทรซ้ำ:
ls -altR . | head -n 3
ฉันจะค้นหาไฟล์ที่แก้ไขล่าสุดในไดเรกทอรี (รวมถึงไดเรกทอรีย่อย) ได้อย่างไร
คำตอบ:
find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "
สำหรับต้นไม้ใหญ่มันอาจยากที่sort
จะเก็บทุกอย่างไว้ในความทรงจำ
%T@
ให้เวลาในการแก้ไขเช่นการประทับเวลายูนิกซ์sort -n
เรียงตามตัวเลขtail -1
ใช้บรรทัดสุดท้าย (การประทับเวลาสูงสุด) cut -f2 -d" "
ตัดฟิลด์แรก (การประทับเวลา) ออกจากเอาต์พุต
แก้ไข:เช่นเดียวกับที่ใช้ใน-printf
GNU เท่านั้นการใช้ ajreals ของstat -c
ก็เช่นกัน แม้ว่ามันจะเป็นไปได้ที่จะทำเช่นเดียวกันใน BSD ตัวเลือกสำหรับการจัดรูปแบบแตกต่างกัน ( -f "%m %N"
มันจะดูเหมือน)
และฉันพลาดส่วนที่เป็นพหูพจน์ ถ้าคุณต้องการที่มากขึ้นแล้วไฟล์ล่าสุดเพียงชนขึ้นโต้แย้งหาง
sort -rn | head -3
sort -n | tail -3
หนึ่งเวอร์ชันให้ไฟล์จากเก่าไปหาใหม่ในขณะที่อีกรุ่นหนึ่งเปลี่ยนจากใหม่สุดไปหาเก่าที่สุด
sort
จะสร้างไฟล์ชั่วคราว ( /tmp
เป็น) ตามที่ต้องการดังนั้นฉันไม่คิดว่าเป็นปัญหา
-printf '%T@ %Tb %Td %TY %p\n'
จะให้การประทับวันที่ (ถ้าจำเป็น) (คล้ายกับls
)
find . -type f -printf '%TF %TT %p\n' | sort | tail -1
ติดตามคำตอบของ @ plundraต่อไปนี้เป็นเวอร์ชั่น BSD และ OS X:
find . -type f -print0 | xargs -0 stat -f "%m %N" |
sort -rn | head -1 | cut -f2- -d" "
find
รองรับ+
แทนได้\;
หรือไม่? เพราะนั่นทำสิ่งเดียวกัน (ผ่านหลายไฟล์เป็นพารามิเตอร์) โดยไม่ต้อง-print0 | xargs -0
ไพพ์
head -1
ไปhead -5
แทนที่จะเรียงลำดับผลลัพธ์และเก็บไว้เฉพาะรายการที่แก้ไขล่าสุดคุณสามารถใช้ awk เพื่อพิมพ์เฉพาะรายการที่มีเวลาแก้ไขมากที่สุด (ในเวลา unix):
find . -type f -printf "%T@\0%p\0" | awk '
{
if ($0>max) {
max=$0;
getline mostrecent
} else
getline
}
END{print mostrecent}' RS='\0'
นี่ควรเป็นวิธีที่เร็วกว่าในการแก้ปัญหาของคุณหากจำนวนไฟล์มีขนาดใหญ่พอ
ฉันได้ใช้อักขระ NUL (เช่น '\ 0') เพราะในทางทฤษฎีชื่อไฟล์อาจมีอักขระใด ๆ (รวมถึงช่องว่างและขึ้นบรรทัดใหม่) แต่ที่จริงแล้ว
หากคุณไม่มีชื่อไฟล์พยาธิวิทยาดังกล่าวในระบบของคุณคุณสามารถใช้อักขระขึ้นบรรทัดใหม่ได้เช่นกัน:
find . -type f -printf "%T@\n%p\n" | awk '
{
if ($0>max) {
max=$0;
getline mostrecent
} else
getline
}
END{print mostrecent}' RS='\n'
นอกจากนี้ยังใช้งานได้ใน mawk ด้วย
mawk
ตัวเลือกมาตรฐาน Debian
ฉันมีปัญหาในการค้นหาไฟล์ที่แก้ไขล่าสุดภายใต้ Solaris 10 find
ไม่มีprintf
ตัวเลือกและstat
ไม่สามารถใช้งานได้ ฉันค้นพบวิธีแก้ไขปัญหาต่อไปนี้ซึ่งทำงานได้ดีสำหรับฉัน:
find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7 }' | sort | tail -1
เพื่อแสดงชื่อไฟล์เช่นกันใช้
find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7," ",$9 }' | sort | tail -1
คำอธิบาย
find . -type f
ค้นหาและแสดงรายการไฟล์ทั้งหมดsed 's/.*/"&"/'
ล้อมชื่อพา ธ ในเครื่องหมายคำพูดเพื่อจัดการกับช่องว่างxargs ls -E
ส่งเส้นทางที่ยกมาไปls
ยัง-E
ตัวเลือกทำให้แน่ใจว่าการประทับเวลาเต็มรูปแบบ (รูปแบบปีเดือนเดือนวันชั่วโมงนาทีวินาทีนาโนวินาที ) จะถูกส่งกลับawk '{ print $6," ",$7 }'
แยกเฉพาะวันที่และเวลาawk '{ print $6," ",$7," ",$9 }'
แยกวันที่เวลาและชื่อไฟล์sort
ส่งคืนไฟล์ที่เรียงลำดับตามวันที่tail -1
ส่งคืนเฉพาะไฟล์ที่แก้ไขล่าสุดดูเหมือนว่าจะทำงานได้ดีแม้จะมีไดเรกทอรีย่อย:
find . -type f | xargs ls -ltr | tail -n 1
ในกรณีที่มีไฟล์มากเกินไปให้ปรับแต่งการค้นหา
-l
ตัวเลือกที่จะls
ดูเหมือนว่าไม่จำเป็น เพียงแค่-tr
ดูเหมือนว่าเพียงพอ
find . -type f -print0 | xargs -0 ls -ltr | tail -n 1
แสดงไฟล์ล่าสุดพร้อมเวลาประทับที่มนุษย์อ่านได้:
find . -type f -printf '%TY-%Tm-%Td %TH:%TM: %Tz %p\n'| sort -n | tail -n1
ผลลัพธ์มีลักษณะเช่นนี้:
2015-10-06 11:30: +0200 ./foo/bar.txt
หากต้องการแสดงไฟล์เพิ่มเติมให้แทนที่-n1
ด้วยจำนวนที่สูงกว่า
ฉันใช้สิ่งที่คล้ายกันตลอดเวลารวมถึงรายการ top-k ของไฟล์ที่แก้ไขล่าสุด สำหรับต้นไม้ไดเรกทอรีขนาดใหญ่ก็อาจจะได้เร็วขึ้นมากเพื่อหลีกเลี่ยงการเรียงลำดับ ในกรณีของไฟล์เพิ่งมีการแก้ไขมากที่สุดอันดับ 1:
find . -type f -printf '%T@ %p\n' | perl -ne '@a=split(/\s+/, $_, 2); ($t,$f)=@a if $a[0]>$t; print $f if eof()'
ในไดเรกทอรีที่มีไฟล์ 1.7 ล้านไฟล์ฉันได้รับไฟล์ล่าสุดใน 3.4 วินาทีเพิ่มความเร็ว 7.5 เท่าเทียบกับโซลูชัน 25.5 โดยใช้การเรียงลำดับ
lastfile
) และจากนั้นคุณสามารถทำสิ่งที่คุณต้องการกับผลลัพธ์เช่นls -l $(lastfile .)
หรือopen $(lastfile .)
(สำหรับ Mac) ฯลฯ
นี่จะให้รายการเรียงลำดับ:
find . -type f -ls 2>/dev/null | sort -M -k8,10 | head -n5
กลับคำสั่งซื้อโดยการวาง '-r' ในคำสั่ง sort หากคุณต้องการชื่อไฟล์เพียงแทรก "awk '{print $ 11}' |" ก่อนหน้า '| ศีรษะ'
บน Ubuntu 13 ต่อไปนี้อาจจะเร็วกว่าเล็กน้อยเนื่องจากจะสลับการเรียงลำดับและใช้ 'head' แทน 'tail' เพื่อลดการทำงาน ในการแสดงไฟล์ใหม่ล่าสุด 11 ไฟล์ในแผนผัง:
หา -type f -printf '% T @% p \ n' | sort -n -r | หัว -11 | ตัด -f2- -d "" | sed -e 's, ^. / ,,' | xargs ls -U -l
สิ่งนี้จะช่วยให้รายการ ls สมบูรณ์โดยไม่ต้องเรียงใหม่และละเว้น './' ที่ 'find' ที่สร้างความรำคาญให้กับทุกชื่อไฟล์
หรือเป็นฟังก์ชันทุบตี:
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
}
ถึงกระนั้นงานส่วนใหญ่ก็ทำโดยวิธีดั้งเดิมของ plundra ขอขอบคุณทุนดรา
ฉันประสบปัญหาเดียวกัน ฉันต้องการค้นหาไฟล์ล่าสุดซ้ำ ๆ หาใช้เวลาประมาณ 50 นาทีในการค้นหา
นี่เป็นสคริปต์เล็กน้อยที่จะทำให้เร็วขึ้น:
#!/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
มันเป็นฟังก์ชั่นวนซ้ำที่ได้รับรายการที่แก้ไขล่าสุดของไดเรกทอรี หากรายการนี้เป็นไดเรกทอรีฟังก์ชันจะเรียกซ้ำและค้นหาในไดเรกทอรีนี้เป็นต้น
ฉันพบว่าสั้นลงและมีผลลัพธ์ที่ตีความได้มากขึ้น:
find . -type f -printf '%TF %TT %p\n' | sort | tail -1
เมื่อกำหนดความยาวคงที่ของชุดข้อมูลรูปแบบ ISO มาตรฐานการเรียงลำดับพจนานุกรมจะใช้ได้และเราไม่ต้องการ-n
ตัวเลือกในการเรียงลำดับ
หากคุณต้องการลบการประทับเวลาอีกครั้งคุณสามารถใช้:
find . -type f -printf '%TFT%TT %p\n' | sort | tail -1 | cut -f2- -d' '
หากการเรียกใช้stat
ไฟล์แต่ละไฟล์นั้นช้าลงคุณสามารถใช้xargs
เพื่อเพิ่มความเร็วให้กับบิต:
find . -type f -print0 | xargs -0 stat -f "%m %N" | sort -n | tail -1 | cut -f2- -d" "
สิ่งนี้จะเปลี่ยนเวลาการแก้ไขซ้ำของไดเรกทอรีทั้งหมดในไดเรกทอรีปัจจุบันเป็นไฟล์ใหม่ล่าสุดในแต่ละไดเรกทอรี:
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
cli แบบง่ายนี้จะทำงาน:
ls -1t | head -1
คุณสามารถเปลี่ยน -1 เป็นจำนวนไฟล์ที่คุณต้องการแสดงรายการ
ฉันพบว่าคำสั่งข้างต้นมีประโยชน์ แต่สำหรับกรณีของฉันฉันต้องดูวันที่และเวลาของไฟล์เช่นกันฉันมีปัญหากับไฟล์หลายไฟล์ที่มีช่องว่างในชื่อ นี่คือวิธีการทำงานของฉัน
find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" " | sed 's/.*/"&"/' | xargs ls -l
คำสั่งต่อไปนี้ทำงานบน Solaris:
find . -name "*zip" -type f | xargs ls -ltr | tail -1
$ find . -type f -not -path '*/\.*' -printf '%TY.%Tm.%Td %THh%TM %Ta %p\n' |sort -nr |head -n 10
จัดการช่องว่างในชื่อไฟล์ได้ดี - ไม่ใช่ว่าควรใช้สิ่งเหล่านี้!
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
อีก find
มากมายตามลิงค์
ในการค้นหาไฟล์ใน / target_directory และไดเรกทอรีย่อยทั้งหมดที่ได้รับการแก้ไขใน 60 นาทีล่าสุด:
$ find /target_directory -type f -mmin -60
หากต้องการค้นหาไฟล์ที่แก้ไขล่าสุดเรียงลำดับตามเวลาย้อนหลังของเวลาอัปเดต (เช่นไฟล์ที่อัปเดตล่าสุดก่อน):
$ find /etc -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r
ฉันชอบอันนี้มันสั้นกว่า:
find . -type f -print0|xargs -0 ls -drt|tail -n 1
ฉันเขียน pypi / github package สำหรับคำถามนี้เพราะฉันต้องการทางออกด้วย
https://github.com/bucknerns/logtail
ติดตั้ง:
pip install logtail
การใช้งาน: ก้อยเปลี่ยนไฟล์
logtail <log dir> [<glob match: default=*.log>]
การใช้งาน 2: เปิดไฟล์ที่เปลี่ยนแปลงล่าสุดในเครื่องมือแก้ไข
editlatest <log dir> [<glob match: default=*.log>]