0

I am currently working on HP-UX and have a cron job which runs every morning which deletes file older than certain number of days based on retention policy. Recently I added a sub directory at the path from where file was getting deleted and wanted to have a different policy for files residing under this sub directory.

Currently my command is as below:

find /directory/backup -mtime +1 -name "FileName*.EXT" -exec rm {} \; 

When this command runs it deletes all the files under backup directory as well as any matching file inside sub directory of backup. I meant there is another directory called backup_db inside backup directory.

pwd
/directory/backup/backup_db

I want to restrict deletion from backup directory only and not from sub directory. How can I achieve that? Any help is highly appreciated.

I tried man rm however didn't find anything which could be of my help.

2 Answers 2

1

With your command line, the find command will produce a series of individual rm commands and execute them. Each rm command will delete one file, specified with a full pathname. So it is not the rm you need to restrict, but the find.

The syntax to do this can be a bit tricky, for historical reasons. You could do it like this:

find /directory/backup ! -path /directory/backup -prune -mtime +1 -type f -name "FileName*.EXT" -exec rm {}\+

The find $DIR ! -path $DIR -prune <desired_conditions> [desired_action] is the POSIX-compatible way to restrict find to a single directory. But it will still list the names of sub-directores of that particular directory, unless you add further conditions.

Using -type f will restrict find from attempting to generate rm commands for sub-directories in the backup directory, which would just create useless error messages: to delete a directory, you'd need a recursive rm or rmdir, and I understood that's something you don't want to do in this case.

Replacing the semicolon at the end of the command specification for -exec with a plus sign will improve performance if there are a lot of files to delete: instead of generating one rm command per file, it will generate as few commands as possible, stuffing as many pathname arguments onto each rm command as the command line length allows. This drastically reduces the need to fork() new processes.

4
  • With above command, I got error for semi colon as --> find: -exec not terminated with ';' Oct 24, 2019 at 11:36
  • Well, the semicolon will also work but with reduced efficiency. The HP-UX find(1) man page says: "In the UNIX 2003 environment, + indicates end of cmd, only if + immediately follows {}." The problem might also be an extra space or a matter of quoting specific to the shell you're using.
    – telcoM
    Oct 24, 2019 at 11:41
  • Didn't get your point. In the answer above, we have rm {}\+. So, you want to change it to rm {}+ Oct 24, 2019 at 11:45
  • Maybe, depending on how your shell (sh? ksh? bash? tcsh? some-other-sh?) handles the plus sign. The standard find command of HP-UX 11.31 is definitely documented to handle the plus sign.
    – telcoM
    Oct 24, 2019 at 11:47
1

Your problem is not with rm but with find. Use the -maxdepth 0 option to limit the search to the starting directory.

If -maxdepth is not supported by your version of find you can also exclude directories with -path and -prune:

To ignore a whole directory tree, use -prune rather than checking every file in the tree. For example, to skip the directory `src/emacs' and all files and directories under it, and print the names of the other files found, do something like this:

find . -path ./src/emacs -prune -o -print

2
  • As far as I know, HP-UX find does not have the -maxdepth option.
    – telcoM
    Oct 24, 2019 at 7:58
  • I am using HP-UX Itanium(B.11.31 U) Oct 24, 2019 at 7:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .