Say I have these files in dir1:

-rw-r--r--  1 user user  10240 Jul  2 11:54 10_data.txt
-rw-r--r--  1 user user  36048 Jul  4 11:56 95_data.txt
-rw-r--r--  1 user user  35634 Jul  7 11:56 01_data.txt
-rw-r--r--  1 user user  10630 Jul  9 11:56 19_data.txt
-rw-r--r--  1 user user  35476 Jul  9 11:57 93_data.txt

I want to be able to copy these files based on their timestamps, specifically the day of the month (2, 4, 7 and 9).


copy 10_data.txt into a directory called 02
copy 19_data.txt into a directory called 09
copy 93_data.txt into a directory called 09

Destination directories (01, 02, 03 , etc.) would already exist, so no need to create them or anything. I plan to run this as a cron job daily after midnight.

Can I use find for this task along with (date +%d) or something like that?

Thank you!


stat is your friend for finding out when a file was modified, or its size, or most any of the file attributes that ls would display.

On FreeBSD, for example, stat -f %Sm -t %d -- foo will show you the day of the month when file foo was last modified, which appears to be what you are after.

No need for find, you can iterate over the files directly, such as in this bash example:

for f in *; do
  d=$(stat -f %Sm -t %d -- "$f")
  cp -p -- "$f" $d/

Responding to your comment that your target OS is RedHat, it appears that RedHat's stat utility does not have the formatting flexibility that FreeBSD's has. You can compare the man pages here.

You may find the command date -r foo "+%d" a suitable substitute. The relevant line of the script would then become:

  d=$(date -r "$f" "+%d")
| improve this answer | |
  • 1
    You might indicate whether this relies on the GNU stat or some other implementation. – Jeff Schaller Jul 9 '19 at 18:16
  • @Jeff-Schaller Good idea. Thank you. – Jim L. Jul 9 '19 at 18:33
  • I am trying to do this on a RHEL system – GA_train Jul 9 '19 at 18:34
  • @GA_t man stat should show you what you need to know. You can play with the stat command manually until you find the options that work for your OS. Then just plug that syntax into the script. – Jim L. Jul 9 '19 at 18:37
  • This "RHEL" comment indicates that the question could use a Linux tag, in order to focus any other answerers on the runtime environment that applies. – Jeff Schaller Jul 9 '19 at 19:23

If you have zsh available, you could do this with its zstat module:

zmodload zsh/stat
for f in *.txt
  cp -p -- "$f" $(zstat -F %d +mtime "$f")/

The zstat -F %d +mtime command asks for the formatted output (-F %d) of the day-of-the-month of the files' modification times. The resulting decimal number is in the range 01 to 31, and is used as the target for the cp command.

| improve this answer | |
  • Nice use of -- to insulate against filenames begining with a hyphen. I borrowed that to improve my answer. In return, may I suggest -p? By default, cp alters the modification date of the file, which is an important piece of the OP's stated problem. Using -p preserves the modification date, which in turn makes it easier to confirm the files were copied to the correct directories. – Jim L. Jul 9 '19 at 19:12
  • Great suggestion, Jim L; thank you! I've incorporated it. – Jeff Schaller Jul 9 '19 at 19:22

You may try like this. I've tested. It should work

cp `ls -ltrh *txt  | awk '{if($7=2){print $NF}}'` `ls -ltrh *txt  | awk '{print $7}'`

I've considered for only day of 2 and directory is on same path. Kindly add other dates and if the directory is another folder then add that as well.

Another assumption is that there is no space in file name.

| improve this answer | |
  • 2
    careful if someone does touch "foo bar.txt" – Jeff Schaller Jul 9 '19 at 18:14
  • Yes. code snippet wont work on that case. Need to handle that. Nice input btw @JeffSchaller – Leon Jul 9 '19 at 18:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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