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?

9
  • So you are looking for files something like file1.txt AND .bashrc ? Jan 21, 2016 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 *. Jan 21, 2016 at 15:15
  • 4
    For the record, it's also useless use of cat Jan 21, 2016 at 16:07
  • 1
    @dr01 yes , i did see that, hence +1ed Jan 21, 2016 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. Jan 21, 2016 at 21:22

3 Answers 3

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

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
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 {*,.*} 
3
  • Or, cat * .* | whatever
    – evilsoup
    Jan 21, 2016 at 21:22
  • It also includes . and .., which sometimes may have unwanted effects. And it generates warnings if there are only hidden files.
    – user23013
    Jan 21, 2016 at 21:23
  • 1
    The brace expansion is not needed, you can do just cat * .* | grep blabla / grep 'blabla' * .*.
    – kos
    Jan 22, 2016 at 2:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .