Linux find command, find 10 latest files recursively regardless of time span
I was told that this is the solution:
find . -type f -printf "%C@ %p\n" | sort -rn | head -n 10
The key point is the printf %C@
placeholder, which is the -ctime
one. I found it by reading man find
.
Result:
1336992789.0000000000 ./Mobilni Telefoni/05. iPhone/03. iPhone 4G Firmware/5.1.1/iPhone3,1_5.1.1_9B206_Restore.ipsw.filepart1336928538.0000000000 ./GPS Navigacije/01. Garmin/03. Garmin Other/test.txt1336922295.0000000000 ./GPS Navigacije/01. Garmin/03. Garmin Other/garmin_kgen_15.exe1336868365.0000000000 ./Mobilni Telefoni/11. Samsung/1. FLASH FILES/1. SRPSKI HRVATSKI JEZICI/E/E2152/E2152_XXJH4_OXFJI2.zip.filepart1336867426.0000000000 ./Mobilni Telefoni/11. Samsung/1. FLASH FILES/1. SRPSKI HRVATSKI JEZICI/E/E210/E210_XFGH2.rar1336866301.0000000000 ./Mobilni Telefoni/11. Samsung/1. FLASH FILES/1. SRPSKI HRVATSKI JEZICI/E/E2330/FlashTool_E2_R6.zip1336865921.0000000000 ./Mobilni Telefoni/11. Samsung/1. FLASH FILES/1. SRPSKI HRVATSKI JEZICI/E/E2330/E2330_OXFKE2.rar1336865409.0000000000 ./Mobilni Telefoni/11. Samsung/1. FLASH FILES/1. SRPSKI HRVATSKI JEZICI/E/E2230/E2230_XXKC1_CDS.zip1336865398.0000000000 ./Mobilni Telefoni/11. Samsung/1. FLASH FILES/1. SRPSKI HRVATSKI JEZICI/E/E2230/E2230_XXKC1_BIN.zip1336864949.0000000000 ./Mobilni Telefoni/11. Samsung/1. FLASH FILES/1. SRPSKI HRVATSKI JEZICI/E/E2230/E2230_OXFKC1_CSC.zip
For a very large list of files, sort(1)
with pipes might not be optimal for resource usage.
sort(1)
could be replaced with perl(1)
and buffer the ten highest entries, only. This has been outlined in unix command: how to get top n records for three, here an adoption for ten records.
It replaces the sort(1)
and head(1)
filters:
find . -type f -printf "%C@ %p\n" | perl -ane ' BEGIN {@top = ([-1]) x 10} if ($F[0] > $top[0][0]) { @top = sort {$a->[0] <=> $b->[0]} @top[1..9], [$F[0], $_]; } END {print for reverse map {$_->[1]} @top}'
The result is identical.
I needed a solution to get the x latest modified files in a directory and use it afterwards in a loop to process them further:
find "/mnt/user/Movie" -iname '*.mkv' -printf "%C@ %p\n" | sort -n | cut -f2- -d" " | tail -10 | tr '\n' '\0' | while IFS= read -r -d '' file; do echo "$file" done
returns:
/mnt/user/Movie/IJ/I (2014)/I (2014).mkv/mnt/user/Movie/AB/B (2010)/B (2010).mkv/mnt/user/Movie/MN/N (1993)/N (1993).mkv/mnt/user/Movie/MN/M (2016)/M (2016).mkv/mnt/user/Movie/KL/K (1984)/K (1984).mkv/mnt/user/Movie/MN/M (1999)/M (1999).mkv/mnt/user/Movie/GH/G (2014)/G (2014).mkv/mnt/user/Movie/MN/M (2002)/M (2002).mkv/mnt/user/Movie/AB/B (2017)/B (2017).mkv/mnt/user/Movie/CD/D (1997)/D (1997).mkv
Change tail -10
to the amount of files that should be returned. Of course you could replace -iname '*.mkv'
against -type f
to cover all files.