0

Actually I’m a newbie at Bash and I’m learning with some hands on.. I used the following stat command:

find "$DIRECTORY"/ -exec stat \{} --printf="%w\n" \; | sort -n -r | head -n 1 > timestamp.txt

where DIRECTORY is any path say, c:/some/path . It contains a lot of folders. I need to extract the creation date of the latest created folder and store it in a variable for further use. Here I started by storing it in a txt file. But the script never completes. It stays stuck at the point it reaches this command line. Please help. I'm using cygwin. I had used --printf="%y\n" to extract last Modified date of the latest folder and it had worked fine.

Kritzii
  • 23
  • 7
  • General suggestion: don't use `c:/some/path` but instead `/cygdrive/c/some/path` – matzeri May 23 '16 at 08:49
  • This could be helpful http://unix.stackexchange.com/a/91200 – Inian May 23 '16 at 10:27
  • @matzei , cygwin cannot find the path if I include /cygdrive in there. – Kritzii May 23 '16 at 10:45
  • @Inian , according to the link you posted, it is not possible to derive the created date of the folder using bas, is it? However, it also says, using "stat" and "%w", the birth date of the file is extracted. This is exactly what I tried, but the script got stuck. – Kritzii May 23 '16 at 10:46
  • @Kritzii: Feel free to check out other answers in the post, I guess support for it is only available in few file systems only like `ntfs-3g` or `ext4` – Inian May 23 '16 at 10:49
  • @Inian : I tried 'stat "$DIRECTORY" > timestamps.txt' . It prints all the data in there. For now, I guess all I can do is read this txt and extract the "Birth date" from it. Thanks for all your time :) – Kritzii May 23 '16 at 10:57
  • @Kritzii: Assuming your file-system supports providing the creation time, can you try the command you ran with a `-type d` option as `find "$DIRECTORY"/ -type d -exec stat \{} --printf="%w\n" \; ` and provide the output here or edit in original post and paste it? – Inian May 23 '16 at 10:58
  • @Kritzii: Please provide the output you have, I can help you get the `date` value from it – Inian May 23 '16 at 10:59
  • @Inian : Yes it did work! I got this as the output: '2016-05-20 12:49:17.222912000 +0530' . Now I need to extract the date part from here. Can you tell me, if I use this command in a folder which is a parent of several more folder layers, does this get applied to the lowest level of the folder structure? – Kritzii May 23 '16 at 11:15
  • @Kritzii: Is the `2016-05-20` the only part needed for you? – Inian May 23 '16 at 11:19
  • @Kritzii: Answer modified to suit the need. Please check it and upvote (and) accept the answer to mark it solved. – Inian May 23 '16 at 11:27
  • @Kritzii: Regarding your question to the application to sub-folders, YES it does. `find` by default applies the actions to all the sub-folders unless you manually restrict it to search within one or two sub-folder levels by specifying `-maxdepth` option. e.g. `-maxdepth 1` will not process sub-folders for more than the 1st level, i.e. the current folder. The answer is updated to extract the date alone. Kindly check the same – Inian May 23 '16 at 11:34

2 Answers2

1

The command is okay (save for escaped \{} which I believe is a mistake in the post). It only seems so that it never finishes, but given enough time, it'll finish.

Direct approach - getting the path

The main bottleneck lies in executing stat for each file. Spawning process under Cygwin is extremely slow, and executing one for each of possibly thousands of files is totally infeasible. The only way to circumvent this is not spawning processes like this.

That said, I see few areas for improvement:

  • If you need only directories like the title of your post suggests, you can pass -type d to your find command to filter out any files.
  • If you need only modification time (see what means directory modification time on Linux here, I guess this may be similar in Cygwin), you can use find's built in facilities rather than stat's like this:

    find "$DIRECTORY"/ -type d -printf '%TY-%Tm-%Td %TH:%TM:%TS %Tz %p\n' \
        | sort -nr \
        | head -n1 \
        | cut -f4 -d' '
    

    Example line before we cut the path with cut - most of stuff in -printf is used to format the date:

    2014-09-25 09:41:50.3907590000 +0200 ./software/sqldeveloper/dataminer/demos/obe
    

    After cut:

    ./software/sqldeveloper/dataminer/demos/obe
    

    It took 0.7s to scan 560 directories and 2300 files. The original command from your post took 28s without -type d trick, and 6s with -type d trick when ran on the same directory.

  • Last but not least, if $DIRECTORY is empty, your command will prune whole directory tree, which will take massive amount of time.

Another approach - getting just the date

If you only need creation date of a subdirectory within a directory (e.g. not the path to the directory), you can probably just use stat:

stat --printf '%Y' "$DIRECTORY"/

I'm not sure whether this includes file creations as well, though.

Alternative approaches

Since getting the last created folder is clearly expensive, you could also either:

  1. Save the directory name somewhere when creating said directory, or
  2. Use naming convention such as ddddyymm-name-of-directory which doesn't require any extra syscalls - just find -type d|....
Community
  • 1
  • 1
rr-
  • 14,303
  • 6
  • 45
  • 67
0

You could do with a -type d option to include only the directories from the current folder, and as discussed in the comments section if you need the output from the stat in just yyyy-mm-dd format, use awk as below.

find "$DIRECTORY"/ -type d -exec stat \{} --printf="%w\n" \; | sort -n -r | head -n 1 | awk '{print $1}'

To store the value in a bash variable:-

$ myvar=$(find "$DIRECTORY"/ -type d -exec stat \{} --printf="%w\n" \; | sort -n -r | head -n 1 | awk '{print $1}')

$ echo $myvar
2016-05-20
Inian
  • 80,270
  • 14
  • 142
  • 161
  • I used this but it produces the "last Modified date" of the current folder only. I need to find the "Created date" of the latest sub-folder present. – Kritzii May 23 '16 at 10:13