1

I'm new in Linux and currently, I want to create a shell script to check any files that have N days old in a specified directory and rename it. Example:

/home/foo/oldfile.txt
2019-01-01

into

/home/foo/oldfile.txt.old

How can I do that?

  • 1
    Do you know how to do any part of this?  Do you know how to find files that are N days old?  Do you know how to rename files?  Please do not respond in comments; edit your question to make it clearer and more complete. – Scott Jun 21 at 4:51
0

To rename any file more than N days old (N=30 in this example), try:

find . -type f -mtime +30 -exec sh -c 'mv -i "$1" "$1.old"' MV {} \;

The above search recursively under the current directory. If you don't want it to descend into subdirectories, use:

find . -maxdepth 1 -type f -mtime +3 -exec sh -c 'mv -i "$1" "$1.old"' MV {} \;

For safety, you might want to try this command first and, if you like the results, remove the echo:

find . -maxdepth 1 -type f -mtime +3 -exec sh -c 'echo mv -i "$1" "$1.old"' MV {} \;

How it works

  • find .

    This starts a find command in the current directory, ..

  • -type f

    This tells find to look only for regular files.

  • -mtime +30

    This tells find to look only for files older than 30 days. Replace 30 with whatever number you want.

    Note that, because find has a peculiar way of rounding off the age of file, the exact cutoff for "more than 30 days old" may not be what you expect. See man find for details.

  • -exec sh -c 'mv -i "$1" "$1.old"' MV {} \;

    This tells find to run a mv command on every file found. The -i option tells mv to ask interactively before overwriting an existing file. There are variety of such options. See man mv for details.

GNU find or similar

Some version of find, such as GNU find, make the use of sh in the above unnecessary (hat tip: rush):

find . -type f -mtime +30 -exec mv -i {} {}.old \;

This is not required by POSIX and thus may not be portable.

  • 1
    You don't need sh -c in exec. Find is able to use multiple {} in -exec statement with \;. Like this: find . -exec mv {} {}.old \; – rush Jun 21 at 8:35
  • 1
    @rush Very good suggestion. Thank you. I just added that to the answer along with a note that that behavior is not required by POSIX: "If a utility_name or argument string contains the two characters "{}", but not just the two characters "{}", it is implementation-defined whether find replaces those two characters or uses the string without change." – John1024 Jun 21 at 18:25

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.