Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am having trouble executing a command which will give me the latest file from another directory.

Example:

ls -tr | tail -n 1  /prj/somedir/anotherdir/closerdir/targetdir

there is a list of files in the targetdir and I need to isolate the newest file from the list.

When I type in the command the problem is that I am using the tail command for a directory.

Example 2:

ls -tr | tail -n 1 

Using the tail command works if I am trying to get the newest file from the directory I am working in but not if I am trying to consume from another directory using the absolute path.

Any suggestions on how I can accomplish this task?

share|improve this question

migrated from stackoverflow.com Jan 13 '12 at 21:12

This question came from our site for professional and enthusiast programmers.

add comment

4 Answers

You don't specify a shell, so I advise you to use Zsh:

ls /path/to/*(.om[1]) 

Here's an example with five file that were all created in the same minute (filenames in the form HHMMSS.txt):

> ls tmp/378142 
total 0
drwxr-xr-x   7 johnsyweb  staff  238 14 Jan 08:23 ./
drwx------  24 johnsyweb  staff  816 14 Jan 08:20 ../
-rw-r--r--   1 johnsyweb  staff    0 14 Jan 08:22 082237.txt
-rw-r--r--   1 johnsyweb  staff    0 14 Jan 08:22 082238.txt
-rw-r--r--   1 johnsyweb  staff    0 14 Jan 08:22 082239.txt
-rw-r--r--   1 johnsyweb  staff    0 14 Jan 08:22 082240.txt
-rw-r--r--   1 johnsyweb  staff    0 14 Jan 08:22 082241.txt

Using echo:

> echo tmp/378142/*(.om[1])
tmp/378142/082241.txt

Using ls:

> ls -laF tmp/378142/*(.om[1]) 
-rw-r--r--  1 johnsyweb  staff  0 14 Jan 08:22 tmp/378142/082241.txt

Explanation:

This uses Zsh's filename expansion.

An asterisk expands to all items in a directory:

> echo tmp/378142/*        
tmp/378142/082237.txt tmp/378142/082238.txt tmp/378142/082239.txt tmp/378142/082240.txt tmp/378142/082241.txt

Modifying this with a ., means all regular files (no directories or symlinks). This is known as a globbing flag:

> echo tmp/378142/*(.)  
tmp/378142/082237.txt tmp/378142/082238.txt tmp/378142/082239.txt tmp/378142/082240.txt tmp/378142/082241.txt

o specifies the sort order, on, is by name:

> echo tmp/378142/*(.on)
tmp/378142/082237.txt tmp/378142/082238.txt tmp/378142/082239.txt tmp/378142/082240.txt tmp/378142/082241.txt

om is sorts by modified time (Om) would reverse the order:

> echo tmp/378142/*(.om)
tmp/378142/082241.txt tmp/378142/082240.txt tmp/378142/082239.txt tmp/378142/082238.txt tmp/378142/082237.txt

[1] selects the first item in the list:

> echo tmp/378142/*(.om[1])
tmp/378142/082241.txt
share|improve this answer
add comment

The answer is very simple - you need to put the path to the directory in question right after the ls -t command or else ls will think you mean the current directory. Then head will read the piped output from ls and echo the top line. Hence, the confusion. Then it's just a matter of doing it right:

$ ls -t /prj/somedir/anotherdir/closerdir/targetdir | head -n 1
share|improve this answer
add comment

I'm unclear about what you want. If you want the name of the most recent file in a directory

  ls -t /prj/somedir/anotherdir/closerdir/targetdir | head -n 1
share|improve this answer
add comment
find /your/path -type f -exec ls -l \{\} \;

Should give you a nice start (only files are listed with verbose ls output. Not just sort the output and print the necessary line.

share|improve this answer
    
Thanks Zsolt! Is there anyway to add a command to this that would display only the latest and ignore the rest? –  Brandi S Jan 13 '12 at 20:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.