3

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?

7
  • 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, 2015 at 6:25
  • Why do you need that the errors are not printed?
    – Braiam
    Aug 10, 2015 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. Aug 10, 2015 at 19:17
  • Thank you for confirming Gilles' answer won't work. Would you have a solution?
    – he wei
    Aug 10, 2015 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, 2015 at 22:00

1 Answer 1

4

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' {} +
11
  • 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, 2015 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? Aug 10, 2015 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. Aug 10, 2015 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, 2015 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. Aug 10, 2015 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.