开发者

unix command to find most recent directory created

I want to copy the files fr开发者_运维百科om the most recent directory created. How would I do so in unix?

For example, if I have the directories names as date stamp as such:

/20110311
/20110318
/20110325


This is the answer to the question I think you are asking.

When I deal with many directories that have date/time stamps in the name, I always take the approach that you have which is YYYYMMDD - the great thing about that is that the date order is then also the alphabetical order. In most shells (certainly in bash and I am 90% sure of the others), the '*' expansion is done alphabetically, and by default 'ls' return alphabetical order. Hence

    ls | head -1
    ls | tail -1

Give you the earliest and the latest dates in the directory.

This can be extended to only keep the last 5 entries etc.


lastdir=`ls -tr <parentdir> | tail -1`

I don't know how to make the backticks play nice with the commenting system here. Just replace those apostrophes with backticks.


After some experimenting, I came up with the following:

The unix stat command is useful here. The '-t' option causes stat to print its output in terse mode (all in one line), and the 13th element of that terse output is the unix timestamp (seconds since epoch) for the last-modified time. This command will list all directories (and sub-directories) in order from newest-modified to oldest-modified:

find -type d -exec stat -t {} \; | sort -r -n -k 13,13

Hopefully the "terse" mode of stat will remain consistent in future releases of stat !

Here's some explanation of the command-line options used:

find -type d                # only find directories
find -exec [command] {} \;  # execute given command against each *found* file.
sort -r                     # reverse the sort
sort -n                     # numeric sort (100 should not appear before 2!)
sort -k M,N                 # only sort the line using elements M through N.

Returning to your original request, to copy files, maybe try the following. To output just a single directory (the most recent), append this to the command (notice the initial pipe), and feed it all into your 'cp' command with backticks.

| head --lines=1 | sed 's/\ .*$//'


The trouble with the ls based solutions is that they are not filtering just for directories. I think this:

cp `find . -mindepth 1 -maxdepth 1 -type d  -exec stat -c "%Y %n" {} \;  |sort -n -r |head -1 |awk '{print $2}'`/* /target-directory/.

might do the trick, though note that that will only copy files in the immediate directory. If you want a more general answer for copying anything below your newest directory over to a new directory I think you would be better off using rsync like:

rsync -av `find . -mindepth 1 -maxdepth 1 -type d  -exec stat -c "%Y %n" {} \;  |sort -n -r |head -1 |awk '{print $2}'`/ /target-directory/ 

but it depends a bit which behaviour you want. The explanation of the stuff in the backticks is:

  • . - the current directory (you may want to specify an absolute path here)
  • -mindepth/-maxdepth - restrict the find command only to the immediate children of the current directory
  • -type d - only directories
  • -exec stat .. - outputs the modified time and the name of the directory from find
  • sort -n -r |head -1 | awk '{print $2}' - date orders the directory and outputs the name of the most recently modified


If your directories are named YYYYMMDD like your question suggests, take advantage of the alphabetic globbing.

Put all directories in an array, and then pick the first one:

dirs=(*/); first_dir="$dirs";

(This is actually a shortcut for first_dir="${dirs[0]}";.)

Similarly, for the last one:

dirs=(*/); last_dir="${dirs[$((${#dirs[@]} - 1))]}";

Ugly syntax, but this is what it breaks down to:

# Create an array of all directories inside the working directory.
dirs=(*/);

# Get the number of entries in the array.
num_dirs=${#dirs[@]};

# Calculate the index of the last entry.
last_index=$(($num_dirs - 1));

# Get the value at the last index.
last_dir="${dirs[$last_index]}";

I know this is an old question with an accepted answer, but I think this method is preferable as it does everything in Bash. No reason to spawn extra processes, let alone parse the output of ls. (Which, admittedly, should be fine in this particular case of YYYYMMDD names.)


please try with following command
ls -1tr | tail -1


find ~ -type d | ls -ltra

This one is simple and useful which I learned recently. This command will show the results in reverse chronological order.


I wrote a command that can be used to identify which folder or files are created in a folder as a newest. That's seems pure :)

#/bin/sh
path=/var/folder_name

newest=`find $path -maxdepth 1 -exec stat -t {} \; |sed 1d |sort -r -k 14 | head -1 |awk {'print $1'} | sed 's/\.\///g'`

find $path -maxdepth 1| sed 1d |grep -v $newest
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜