4

I run command to search for phrase in all files:

cat *.* | grep blabla

It works fine but I got problem with hidden files and directories. Command simply not deals with them. Ho to solve this problem?

Braiam
  • 67,791
  • 32
  • 179
  • 269
vico
  • 4,527
  • 21
  • 58
  • 87
  • So you are looking for files something like file1.txt AND .bashrc ? – Sergiy Kolodyazhnyy Jan 21 '16 at 15:10
  • If you want to also cat from hidden files you'll have to eliminate that first *. You could do something like cat *.* | grep blabla && cat .* | grep blabla. By the way, if you want to cat all the files in a directory you could simple use cat *. – Eduardo Cola Jan 21 '16 at 15:15
  • @EduardoCola You mean cat *.* | grep blabla; cat .* | grep blabla; in your command, if the first command exits with a nonzero status the second won't be executed, which is not what you want. But there's a better method for this -- please see my answer below. – dr_ Jan 21 '16 at 15:50
  • 4
    For the record, it's also useless use of cat – Sergiy Kolodyazhnyy Jan 21 '16 at 16:07
  • @Serg This also was in my answer :) – dr_ Jan 21 '16 at 16:39
  • 1
    @dr01 yes , i did see that, hence +1ed – Sergiy Kolodyazhnyy Jan 21 '16 at 17:01
  • 1
    WARNING: Most methods to include files starting with a dot in a command's argument list will also include the directory link ".." . Combine that with any recursive command, and the consequences can be ... intense. – rackandboneman Jan 21 '16 at 21:22
  • @Serg This is not an entirely useless use of cat. It will actually concatenate the files and pipe the concatenated result to grep. You could not have used <* in place of it. And grep blabla * would produce a different result, because it will include the name of each file in the output, which would not happen with cat. If you can remember that grep has a -h option, you can avoid using cat. But if you don't recall that option it may well be faster to use cat than to look it up in the grep man page. – kasperd Jan 22 '16 at 09:11
  • Are you sure *.* is really what you wanted to write in the first place? It will match entries which have a . in their name but skip all those with no . in their name. I think what you really wanted was *. – kasperd Jan 22 '16 at 09:13

3 Answers3

7

By default, hidden files (i.e. those starting with a period) are excluded from the bash shell's glob expansion. However you can alter that using the dotglob setting e.g.

$ mkdir dir
$ touch dir/.hidden dir/visible

$ echo dir/*
dir/visible

$ shopt -s dotglob
$ echo dir/*
dir/.hidden dir/visible

You can unset the option afterwards with shopt -u dotglob

Byte Commander
  • 107,489
steeldriver
  • 136,215
  • 21
  • 243
  • 336
3

Use find command with logical OR flag (-o ) and -exec . . .\+ flag

 find . -maxdepth 1 \( -iname "*.*" -o -iname ".*"   \) -exec grep "MySearchTerm" {} \+ 

Explanation:

  • find is a recursive command that searches files in specified directory. In this case , it is . the current working directory.
  • -maxdepth flag tells us to stay only in current directory. If you want to go recursivelly or specify how many subdirectories to descent, change 1 to number of levels you wanna go.
  • \( . . .\) part prevents shell of treating that as subshell, rather treating it as grouping of arguments to find.
  • -iname flags allow specifying for which filenames to search.
  • -o flag will tell find to search for files *.* or files that start with leading dot , the hidden files.
  • -exec . . .{} structure allows running specific command to operate on files found. \+ will tell find to take all the files as arguments for the command you want to run, in this case grep.

Here's a small example, where you can see SEARCHFILE.txt and .SEARCHFILE.txt are both found:

DIR:/xieerqi
skolodya@ubuntu:$ find . -maxdepth 1 \( -iname "*.*" -o -iname ".*"   \) -exec grep "HelloWorld" {} \+ 2>/dev/null           
./SEARCHFILE.txt:HelloWorld ! I'm found
./localDir.txt:HelloWorld.so
./localDir.txt:HelloWorld.c
Binary file ./2015-05-05-raspbian-wheezy.img matches
./.SEARCHFILE.txt:HelloWorld ! I'm found
Sergiy Kolodyazhnyy
  • 105,154
  • 20
  • 279
  • 497
3

"Hidden files" are simply files whose name starts with a dot. In GUIs applications these files are usually not shown, whence their name.

You can use shell globbing:

cat {*,.*} | grep blabla

The previous command include all files with no dot (*) and all files that start with a dot (.*).

By the way, this is an useless use of cat, and you should instead write your command as:

grep blabla {*,.*} 
dr_
  • 817