LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   sort files inside a directory and sub-directories by latest created (https://www.linuxquestions.org/questions/linux-software-2/sort-files-inside-a-directory-and-sub-directories-by-latest-created-742173/)

walidaly 07-23-2009 03:24 AM

sort files inside a directory and sub-directories by latest created
 
I have a huge number of JPG files inside a directory and its sub directories, I need to select the latest 10 files created.
I tried
Code:

ls -tR  /dir/  |  grep .jpg | head -n 20
but that gives me results from only one sub-directory and they are different from
Code:

find /dir/ -type f -mmin -10

colucix 07-23-2009 04:14 AM

Use xargs to process all the file together:
Code:

find /dir -type f -iname \*.jpg -print0 | xargs -0 ls -lrt | tail -10
However, if you have a very large number of files the list of arguments passed to xargs can be too long, resulting in an error. In that case we have to find another way.

PS - You can restrict the search using -newer. For example, if you know that the last 10 files are created in the last 3 hours you can do something like:
Code:

$ touch -t $(date -d "3 hours ago" +%Y%m%d%H%M) /tmp/dummy.file
$ find /dir -type f -iname \*.jpg -newer /tmp/dummy.file -print0 | xargs -0 ls -lrt | tail -10


chrism01 07-23-2009 07:42 PM

Just FYI, Unix doesn't actually have a creation time:
Quote:

Three fields in the inode structure contain the last access, change, and modification times: atime, ctime, and mtime. The atime field is updated each time the pointer to the file's data blocks is followed and the file's data is read. The mtime field is updated each time the file's data changes. The ctime field is updated each time the file's inode changes. The ctime is not creation time; there is no way under standard Unix to find a file's creation time.

jay73 07-24-2009 12:30 AM

Quote:

Just FYI, Unix doesn't actually have a creation time:
But wouldn't you have something similar if you mounted your filesystem(s) noatime? Look at the difference between access time and the other time variables in the example here:

Quote:

devbox@Selena:~/dumpster$ stat file2
File: `file2'
Size: 7 Blocks: 8 IO Block: 4096 regular file
Device: 826h/2086d Inode: 134498235 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1001/ devbox) Gid: ( 1001/ devbox)
Access: 2009-07-23 00:04:41.012207741 +0200
Modify: 2009-07-24 07:26:07.125808381 +0200
Change: 2009-07-24 07:26:07.125808381 +0200

colucix 07-24-2009 01:05 AM

Quote:

Originally Posted by chrism01 (Post 3618269)
Just FYI, Unix doesn't actually have a creation time:

That's right. In this case we don't speak about "creation date". Just a matter of terminology: "file created", in place of "file modified". I would add that the new ext4 filesystem will store creation time as well. Here is a comparison table of filesystems that shows which support cration timestamps and which not.

chrism01 07-24-2009 01:58 AM

For most people, mtime is what they really care about. Sometimes atime if its a read-only file.
Up until/including ext3, you have to embed the creation date in the filename (or store it elsewhere). eg

somelogname_YYYYMMDD-HHMM.log

so it sorts easily.

jschiwal 07-24-2009 03:36 AM

The output of the a timestamp field needs to be in a form that is sortable. The output of "ls -l ..." can change form depending on the age of the file.

Here I use seconds, which a numeric sort handles easily.
Code:

find /path/to/pics/dir/ -iname "*.jpg" -printf "%A@\t%p\n" | sort -nr | head -n 10 | cut -f2-
The timestamp in seconds is printed, followed by a tab, and then the filename.
To deal with filenames with whitespace, pipe the output through "tr '\n' '\0'" and use "xargs -0" to process the files.

You might want to add an -mtime option in the find command to limit the number of files `find' finds. A very long list could cause the sort command to run to slow. The -mtime argument you use might return 100 filenames, for example, but this is a lot better than piping 10,000 lines into sort.

walidaly 07-24-2009 07:51 PM

that is very helpful jschiwal...thank you
another thing...
how to extract the file names from image path and put them to a file
I tried
Code:

find /path/to/pics/dir/ -iname "*.jpg" -printf "%A@\t%p\n" | sort -nr | head -n 10 | grep "^.*([^/]*).jpg$" > file

jschiwal 07-25-2009 02:45 PM

You need the pathnames to move the files.

You could use sed to filter the first list, to produce a list of filenames without the directory part:

sed 's/.*\/\([^/]*$\)/\1/' file

You could also rerun the original command, but use -printf "%A@\t%f\n". Provided a new file wasn't saved in the meantime.

The -printf command is very flexible. Use it to format the results the way you need them.


All times are GMT -5. The time now is 11:40 AM.