7

I'm trying to delete all files containing a certain text like this:

$ find ~/Library/MobileDevice/Provisioning\ Profiles/* -exec grep -l "text to search for" '{}' \; -delete
/Users/build/Library/MobileDevice/Provisioning Profiles/06060826-3fb2-4d71-82c6-7b9d309b08d6.mobileprovision
find: -delete: /Users/build/Library/MobileDevice/Provisioning Profiles/06060826-3fb2-4d71-82c6-7b9d309b08d6.mobileprovision: relative path potentially not safe

However, as you can see, it's throwing a warning and then does not delete the file. How can I resolve this error?

This is on a Mac.

14

macOS find is based on an older version of FreeBSD find whose -delete would not remove the files that were given as argument.

When you do:

find dir/* ... -delete

Your shell is expanding that dir/* glob into a list of file paths (excluding the hidden ones, while find itself will not exclude the hidden files it finds in any of those dirs), so find receives something like:

find dir/dir1 dir/dir2 dir/file1 dir/file2... ... -delete

If dir/file1 matches macOS find's -delete will refuse to delete it. It will happily delete a dir/dir1/.somefile if it matches though.

That was changed in FreeBSD in 2013, but the change apparently didn't make it to macOS. Here, the work around is easy: use find dir (or find dir/ if you want to allow for dir to be a symlink to a directory and find to descend into it) instead of find dir/*. So, in your case:

find ~/Library/MobileDevice/Provisioning\ Profiles/ \
  -exec grep -l "text to search for" '{}' \; -delete

Or use the more efficient grep -l --null | xargs -0 approach.

1
  • Now works on macOS (bigsur 11.5.2) if you add -mindepth to the call as per another answer. Both dir/* and dir/ same results.
    – Claud H
    Oct 26 '21 at 8:50
8

I ran into this problem on macOS deleting everything except archives from a directory tree:

find top ! -name "*.tar.gz" -print -delete
... snip ...
top
find: -delete: top: relative path potentially not safe

The solution was adding -mindepth 1 to exclude the top directory

find top/path -mindepth 1 ! -name "*.tar.gz" -print -delete
2

Try: find ~/Library/MobileDevice/Provisioning\ Profiles/ -type f -name "name to match" -delete

Edit - first code is not abswer for question, try this: find ~/Library/MobileDevice/Provisioning\ Profiles/ -type f -exec grep -l --null "pattern in file" {} + | xargs -0 rm

9
  • 1
    This is searching for a filename pattern. OP wants to find files which contain a certain string/text.
    – Michael D.
    Jan 30 '19 at 11:20
  • @MichaelD. Oh, you are right, my bad.
    – Matej
    Jan 30 '19 at 11:25
  • You can't use xargs in general on the output of find, but especially here, it won't work as the paths of the files contain spaces (all whitespace, quotes backslashes are a problem with find | xargs) Jan 30 '19 at 12:19
  • 2
    No, I meant -exec grep -q pattern {} \; -print0 | xargs -0 rm. macOS grep should also support GNU's --null option so -exec grep -l --null pattern {} + | xargs -0 rm should also work (and avoid running one grep per file). Jan 30 '19 at 12:37
  • 1
    Yes. It's correct (there are some race condition issues linked to using xargs rm instead of -delete, but probably not worth working around here as we're presumably not removing files from a directory under control of potentially malicious actors). Jan 30 '19 at 12:51
0

This is searching for string err in all files in /var/log/ recursive.

I'm not sure if cut, uniq and xargs is available on Mac and this is not using find.

grep -r "err" /var/log/ | cut -d: -f1 | uniq | xargs echo

Replace echo with rm to delete the files.

1
  • 'find', cut, uniq and xargs are standard Unix utilities available on any Unix platform.
    – Kusalananda
    Jan 30 '19 at 12:13
0

You need to change the star sign (*) in the folder path (right after find) to a dot (.)

i.e., find dir/* ... -delete ==> find dir/. ... -delete

0

For me, this simply worked, using the -name option (find <root_dir> -name <glob_pattern>), instead of using globbing in the root path itself:

find ./tmp -name "*.json" -ctime +60s -type f -delete

thanks to this answer here on this same page for inspiration ;) https://unix.stackexchange.com/a/573178/411724

1
  • oops just realized this isn't exactly what OP is about, but since I had this error for doing the above (using glob for base path) I guess this might help others too.
    – Tchakabam
    May 8 '21 at 0:30

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.