What script would allow me to grep a keyword and print the filename containing the keyword inside the file content, for example 'Carhart' inside all .sas files in all subdirectories? I tried something like the following but it doesn't work:

(find . -name '*.sas' -prune -type f -exec grep 'Carhart' > /dev/tty) >& /dev/null

The script would satisfy two conditions

  1. It runs on tcsh on Solaris on SPARC-Enterprise, which is certified POSIX
  2. It does not generate 'Permission denied' lines on directories which I have no permission to search and/or read. ( find / -name '*.sas' -prune > /dev/tty ) > & /dev/null

Since ( find / -name '*.sas' -prune > /dev/tty ) > & /dev/null works without reporting permission denied error, how can I modify this simple line to incorporate grep?

  • Note that tcsh is not and never will be certified to be POSIX compliant. On Solaris, you need to run /usr/xpg4/bin/sh as your shell and have the POSIX PATH set to `getconf PATH) to comply. – jlliagre Aug 10 '15 at 6:25
  • Why do you need that the errors are not printed? – Braiam Aug 10 '15 at 18:47
  • 1
    Running truss -a -f -u :: find /var ... seems to confirm that it works like github.com/illumos/illumos-gate/blob/master/usr/src/cmd/find/… , that is, it calls nftw and if nftw detects a directory that is not readable, find outputs an error message before doing anything else (even before doing -type d -a test_for_unreadability -a -prune) . The best thing to do may be to filter out the error messages on stderr rather than trying to come up with a set of conditions to pass to find that will make it avoid unreadable directories. – Mark Plotnick Aug 10 '15 at 19:17
  • Thank you for confirming Gilles' answer won't work. Would you have a solution? – he wei Aug 10 '15 at 21:00
  • 1
    He's not only saying that Gilles answer will not work, but any answer at all, because find tries to open() first. You will have them printed anyways. Is there a reason why you don't want them to be printed? – Braiam Aug 10 '15 at 22:00

To make grep print only the file name, pass the -l option. To search for a substring rather than a regular expression, pass the -F option.

To search recursively for files whose name matches a certain pattern, use find with the -type f and -name PATTERN primaries. Use -exec to invoke grep.

find . -name '*.sas' -type f -exec grep -F -l 'Carhart' {} +

If you want to avoid errors from directories that you aren't allowed to traverse, you can either use -perm, -user and -group to analyze permissions (which is difficult to get right, and won't work if you have ACL), or call test (which is slowed because it's an external program, but is more reliable).

find . -type d ! -exec test -r {} -a -x {} \; -prune -o \
       -name '*.sas' -type f -exec test -r {} \; -exec grep -F -l 'Carhart' {} +
  • I'm sorry even your second command would generate errors "find: cannot read dir ./var/sadm/pkg/SUNWdtdmn/save: Permission denied find: cannot read dir ./var/sadm/pkg/SUNWdthez/save: Permission denied .... " – he wei Aug 10 '15 at 0:43
  • @hewei That would happen only if the permission bits indicate that you can access these directories, but the access actually fails. As far as I know this shouldn't happen for normal filesystems on Solaris (it can happen with “weird” filesystems such as Samba). What filesystem is that directory on? – Gilles 'SO- stop being evil' Aug 10 '15 at 0:49
  • @hewei Use backticks for code. Click the “help” button near the “Add Comment” button to see help on formatting code. This script is very complex, I don't understand what you're trying to do. – Gilles 'SO- stop being evil' Aug 10 '15 at 0:51
  • That complex script , which I don't understand either, was the answer from jlliagre on <unix.stackexchange.com/questions/222175/…> – he wei Aug 10 '15 at 0:58
  • @hewei The only effect of -prune is to stop descending into directories whose name matches *.sas, it doesn't change what's done on other directories or what's done on non-directories matching *.sas. So see my first command. – Gilles 'SO- stop being evil' Aug 10 '15 at 7:37

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.