Use the shell globbing syntax:
grep pattern -r --include=\*.cpp --include=\*.h rootdir
The syntax for --exclude
is identical.
Note that the star is escaped with a backslash to prevent it from being expanded by the shell (quoting it, such as --include="*.cpp"
, would work just as well). Otherwise, if you had any files in the current working directory that matched the pattern, the command line would expand to something like grep pattern -r --include=foo.cpp --include=bar.cpp rootdir
, which would only search files named foo.cpp
and bar.cpp
, which is quite likely not what you wanted.
Update 2021-03-04
I've edited the original answer to remove the use of brace expansion, which is a feature provided by several shells such as Bash and zsh to simplify patterns like this; but note that brace expansion is not POSIX shell-compliant.
The original example was:
grep pattern -r --include=\*.{cpp,h} rootdir
to search through all .cpp
and .h
files rooted in the directory rootdir
.
And for vim
7.4+ you can use (preferably on your .vimrc) (thanks to 罗泽轩 for that last bit of news!):
:set nofixendofline
Now regarding older versions of vim
.
Even if the file was already saved with new lines at the end:
vim -b file
and once in vim:
:set noeol
:wq
done.
alternatively you can open files in vim with :e ++bin file
Yet another alternative:
:set binary
:set noeol
:wq
see more details at Why do I need vim in binary mode for 'noeol' to work?
Best Solution
Because that’s how the POSIX standard defines a line:
Therefore, lines not ending in a newline character aren't considered actual lines. That's why some programs have problems processing the last line of a file if it isn't newline terminated.
There's at least one hard advantage to this guideline when working on a terminal emulator: All Unix tools expect this convention and work with it. For instance, when concatenating files with
cat
, a file terminated by newline will have a different effect than one without:And, as the previous example also demonstrates, when displaying the file on the command line (e.g. via
more
), a newline-terminated file results in a correct display. An improperly terminated file might be garbled (second line).For consistency, it’s very helpful to follow this rule – doing otherwise will incur extra work when dealing with the default Unix tools.
Think about it differently: If lines aren’t terminated by newline, making commands such as
cat
useful is much harder: how do you make a command to concatenate files such thatb.txt
andc.txt
?Of course this is solvable but you need to make the usage of
cat
more complex (by adding positional command line arguments, e.g.cat a.txt --no-newline b.txt c.txt
), and now the command rather than each individual file controls how it is pasted together with other files. This is almost certainly not convenient.… Or you need to introduce a special sentinel character to mark a line that is supposed to be continued rather than terminated. Well, now you’re stuck with the same situation as on POSIX, except inverted (line continuation rather than line termination character).
Now, on non POSIX compliant systems (nowadays that’s mostly Windows), the point is moot: files don’t generally end with a newline, and the (informal) definition of a line might for instance be “text that is separated by newlines” (note the emphasis). This is entirely valid. However, for structured data (e.g. programming code) it makes parsing minimally more complicated: it generally means that parsers have to be rewritten. If a parser was originally written with the POSIX definition in mind, then it might be easier to modify the token stream rather than the parser — in other words, add an “artificial newline” token to the end of the input.