How to use grep on all files non-recursively in a directory?
In Bash, a glob will not expand into hidden files, so if you want to search all the files in a directory, you need to specify hidden files .*
and non-hidden *
.
To avoid the "Is a directory" errors, you could use -d skip
, but on my system I also get an error grep: .gvfs: Permission denied
†, so I suggest using -s
, which hides all error messages.
So the command you are looking for is:
grep -s "string" * .*
If you are searching files in another dir:
grep -s "string" /path/to/dir/{*,.*}
Another option is to use the dotglob
shell option, which will make a glob include hidden files.
shopt -s dotglob
grep -s "string" *
For files in another dir:
grep -s "string" /path/to/dir/*
† Someone mentioned that I shouldn't get this error. They may be right - I did some reading but couldn't make heads or tails of it myself.
You need the -d skip
option added on.
Grep is searching inside of files. You can search recursively, as you said, if you want to search files inside of a directory.
By default, grep will read all files, and it detects the directories. Because by default you have not defined what to do with the directories with the
-d
option, it give error output.Searching just within the parent directory would be
grep -d skip "string" ./*
Old timers would probably do this:
find . -type f -print0 | xargs -0 grep "string"
Rephrasing - you want to grep the files in one level of subdirectory, but not recurse though all sub-sub directories?
grep forthis * */*
Or if you don't want the files in the current directory
grep forthis */*
Note this won't find directories starting with a dot.
grep forthis .*/* */*
should do that job.
There's also -maxdepth
and -mindepth
restriction parameters available to the find
command too.
You can think like this, for example using grep.
grep -l PATH ~/.[^.]*
So this search for string "PATH" listing name of the files below the user's home directory, only for files that start with a dot .
/root/.bash_history
/root/.bash_profile
grep: /root/.cache: Is a directory
grep: /root/.config: Is a directory
grep: /root/.dbus: Is a directory
Using grep PATH ~/.[^.]* you'll see all occurrence, including line with searching keyword.
/root/.bash_history:echo $PATH
/root/.bash_history:echo $PATH
/root/.bash_history:PATH=$PATH:~/bin
/root/.bash_history:echo $PATH
/root/.bash_profile:PATH=$PATH:$HOME/bin
/root/.bash_profile:export PATH
grep: /root/.cache: Is a directory
grep: /root/.config: Is a directory
grep: /root/.dbus: Is a directory
To get rid of error redirect to /dev/null for example
grep PATH ~/.[^.]* 2>/dev/null
/root/.bash_history:echo $PATH
/root/.bash_history:echo $PATH
/root/.bash_history:PATH=$PATH:~/bin
/root/.bash_history:echo $PATH
/root/.bash_profile:PATH=$PATH:$HOME/bin
/root/.bash_profile:export PATH
So you can apply this pattern for searching "Apache" string in files from /etc directory-looking only in files below this main directory. You see that this don't return from /etc/httpd/conf/httpd.conf
grep Apache /etc/[^.]* 2>/dev/null
/etc/passwd:apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
/etc/services:derby-repli 4851/tcp # Apache Derby Replication
/etc/services:derby-repli 4851/udp # Apache Derby Replication