开发者

ack misses results (vs. grep)

I'm sure I'm misunderstanding something about ack's file/directory ignore defaults, but perhaps somebody could shed some light on this for me:

mbuck$ grep logout -R app/views/
Binary file app/views/shared/._header.html.erb.bak.swp matches
Binary file app/views/shared/._header.html.erb.swp matches
app/views/shared/_header.html.erb.bak: <%= link_to logout_text, logout_path, { :title => logout_text, :class => 'login-menuitem' } %>
mbuck$ ack logout app/views/
mbuck$

Whereas...

mbuck$ ac开发者_JAVA技巧k -u logout app/views/
Binary file app/views/shared/._header.html.erb.bak.swp matches
Binary file app/views/shared/._header.html.erb.swp matches
app/views/shared/_header.html.erb.bak
98:<%= link_to logout_text, logout_path, { :title => logout_text, :class => 'login-menuitem' } %>

Simply calling ack without options can't find the result within a .bak file, but calling with the --unrestricted option can find the result. As far as I can tell, though, ack does not ignore .bak files by default.

UPDATE

Thanks to the helpful comments below, here are the new contents of my ~/.ackrc:

--type-add=ruby=.haml,.rake
--type-add=css=.less


ack is peculiar in that it doesn't have a blacklist of file types to ignore, but rather a whitelist of file types that it will search in.

To quote from the man page:

With no file selections, ack-grep only searches files of types that it recognizes. If you have a file called foo.wango, and ack-grep doesn't know what a .wango file is, ack-grep won't search it.

(Note that I'm using Ubuntu where the binary is called ack-grep due to a naming conflict)

ack --help-types will show a list of types your ack installation supports.


If you are ever confused about what files ack will be searching, simply add the -f option. It will list all the files that it finds to be searchable.


ack --man states:

If you want ack to search every file, even ones that it always ignores like coredumps and backup files, use the "−u" switch.

and

Why does ack ignore unknown files by default? ack is designed by a programmer, for programmers, for searching large trees of code. Most codebases have a lot files in them which aren’t source files (like compiled object files, source control metadata, etc), and grep wastes a lot of time searching through all of those as well and returning matches from those files.

That’s why ack’s behavior of not searching things it doesn’t recognize is one of its greatest strengths: the speed you get from only searching the things that you want to be looking at.

EDIT: Also if you look at the source code, bak files are ignored.


Instead of wrestling with ack, you could just use plain old grep, from 1973. Because it uses explicitly blacklisted files, instead of whitelisted filetypes, it never omits correct results, ever. Given a couple of lines of config (which I created in my home directory 'dotfiles' repo back in the 1990s), grep actually matches or surpasses many of ack's claimed advantages - in particular, speed: When searching the same set of files, grep is faster than ack.

The grep config that makes me happy looks like this, in my .bashrc:

# Custom 'grep' behaviour
# Search recursively
# Ignore binary files
# Output in pretty colors
# Exclude a bunch of files and directories by name
# (this both prevents false positives, and speeds it up)
function grp {
    grep -rI --color --exclude-dir=node_modules --exclude-dir=\.bzr --exclude-dir=\.git --exclude-dir=\.hg --exclude-dir=\.svn --exclude-dir=build --exclude-dir=dist --exclude-dir=.tox --exclude=tags "$@"
}

function grpy {
    grp --include=*.py "$@"
}

The exact list of files and directories to ignore will probably differ for you: I'm mostly a Python dev and these settings work for me.

It's also easy to add sub-customisations, as I show for my 'grpy', that I use to grep Python source.

Defining bash functions like this is preferable to setting GREP_OPTIONS, which will cause ALL executions of grep from your login shell to behave differently, including those invoked by programs you have run. Those programs will probably barf on the unexpectedly different behaviour of grep.

My new functions, 'grp' and 'grpy', deliberately don't shadow 'grep', so that I can still use the original behaviour any time I need that.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜