Find and copy .zip file based on today's date

Hi Team,
I'm new to unix and i have a requirement to copy or move files from one directory to another based on current date mentioned in the .zip file name. Note that i need to copy only the recent zip file. please help me with the code
i tried the code as:

#! /usr/bin/sh
find /var/tmp/NewFile/TestM/ -name '*.txt' -mtime 0 | while read FILE
do
        echo "Found file $FILE"
done

But, this gives only if the file is found or not but i need to copy as well if zip file is found.
Data :

-rw-rw-rw-   1 user  user     1697 Jul 02 09:57 file_02072019.txt
-rw-rw-rw-   1 user  user      103 Jul 02 09:57 file_02072019.zip

OK, this is a good start. The find utility provides a list of filenames fitting the clauses you specifiy. Here is the principle of how it works. I suggest you try the following commands on the commandline to get acquainted:

find /var/tmp/NewFile/TestM/

will list everything in the directory: files, directories, whatever. As you are interested only in files you can specify:

find /var/tmp/NewFile/TestM/ -type f

The -type f limits the output to only files, skipping directories and other things. But you are not interested in all files, only the ones with a certain extension: "zip", if i got you right. Therefore:

find /var/tmp/NewFile/TestM/ -type f -name "*zip"

This will reduce the outcome further to only files ( -type f ) named "zip" ( -name "*zip" ) at the end. You can use other clauses (as you have done) to further limit the result set.

Right now you pipe this list into a while-loop and process it there. In the version you showed us only an echo -statement is inside the loop and therefore the filename is simply displayed, nothing else. You could now put other commands into the loop to process the files in the way you want, i.e.:

#! /usr/bin/sh
find /var/tmp/NewFile/TestM/ -name '*zip' -mtime 0 | while read FILE
do
        echo "Found file $FILE"
        cp "$FILE" /some/where/else
done

but there is a much better and more elegant approach: find can itself process the files found using the -exec clause: the filename found is represented by "{}" and you need to terminate the "commandline" by "\;". Therefore:

find /var/tmp/NewFile/TestM/ -name '*zip' -mtime 0 -exec cp {} /some/where/else \;

I suggest you consult the man pages about find about the exact terms and limitations of this procedure.

I hope this helps.

bakunin

1 Like

Hi,

There's a few ways to approach this, but using the find command as you're starting to do will certainly do the trick. However, as things stand, your find command isn't actually going to do anything other than print out the message Found file <FILENAME> for all files with the extension txt underneath the directory /var/tmp/NewFile/Test .

Taking things in turn:

-name '*.txt'
This will match all files whose name ends with the extension .txt

-mtime 0
Not one I've seen often phrased in this particular way, but this will have the effect of matching all files modified between now (the time when the command is run) and one day ago. Personally I usually phrase this as -mtime -1 (meaning all files modified less than one day ago), but this is fine, if that's what you're wanting to find.

Now, you then go on to pipe the output into a while loop for some reason, which I'm not too clear on - you don't really have to do this, as the find command is capable of operating directly on what it finds via the -exec flag. This will cause any given command to be executed on whatever the find command ha found.

So, for example: let's say you wanted to find all files whose extension was .txt and which were modified less than one day ago, and then you wanted to move them to another directory (let's call it /tmp/recent-files for the sake of our example). This could be achieved with a single find command like this:

find /var/tmp/NewFile/Test -mtime 0 -name '*.txt' -exec mv -fv \{\} /tmp/recent-files/ \;

So let's look at this last bit in more detail, as this is probably new to you.

Firstly, -exec is the flag that tells find that we want to run a command on all the things we've found that match our patterns up to this point.

Next, we have mv -fv \{\} /tmp/recent-files/ \; - this is the actual command we want to run, used with some find -specific syntax. Breaking it down further: mv -fv is the first part of our move command, and is just as normal (the flags you use here can be whatever you want, but I went with -fv to ensure files get moved no matter what, and that it will print the name of each file it moves).

Now, here comes the interesting bit. The meaning of \{\} is "the filename of whatever matched file we are currently considering". So the two curly brackets are a stand-in for the filename of whatever thing find has found which matched your conditions.

Next is the second part of the mv command, which is the destination you want to move things to - in our case, that's /tmp/recent-files/ .

Lastly, we end with a single semi-colon symbol, \; . This marks the end of our -exec to the find command.

So the end result of this particular find command is to match all files underneath /var/tmp/NewFile/test which were modified between now and 1 days ago and which end with the extension .txt , and to move all such matching files one at a time into the directory /tmp/recent-files/ .

Hope this helps ! You should be able to play about with the syntax of the above to achieve whatever result you're wanting, but if you have any other questions let me know and I'll see if I can lend a further hand.

1 Like

Thanks a lot bakunin and drysdalk for providing detailed explanation. It made my understanding clear. I think ill use exec command as suggested instead of while loop for this operation.