Portrait of Michael Limberger

Michael Limberger

Need me? Email mike@limberger.ca

Regex

Ack - Searching Like A Pro

grep, but for people who live in code

ack is a search tool designed for programmers. It is like grep, but it ignores version control directories (.git, .svn), ignores binary files automatically, color-codes output by default, understands file types (--perl, --python, --js), and is recursive by default.

Think of it as grep for code. It works great for any text search.

The shape of a command

Show me.

ack [options] PATTERN [directory]

If you do not specify a directory, ack searches the current directory and all subdirectories.

Your first search

Use the practice folder:

cd ~/regex-practice
ack "Hello"

Output shows the filename, line number, and matching line with the match highlighted.

Case

By default, ack is case-sensitive. ack "hello" will not find "Hello". ack "Hello" will.

Use -i for case-insensitive search: ack -i "hello" finds hello, Hello, HELLO. This is your most common flag. Use it often.

Patterns, not just words

ack uses Perl-style regex by default. All those patterns we learned work here:

Show me.

ack "\d+"           # Lines containing digits
ack "TODO|FIXME"    # Lines with TODO or FIXME
ack "^Error"        # Lines starting with "Error"
ack "\.txt$"        # Lines ending with .txt

Remember: you are searching the CONTENTS of files, not filenames.

Finding files by what is inside

Show me.

ack -i "error"
ack "port\s*=\s*\d+"
ack "TODO:"
ack "function\s+\w+"

Case-insensitive "error". A port assignment. TODO comments. A very rough function definition.

Word boundaries matter

Without them, ack "log" matches log, login, catalog, dialogue, blog.

With them:

ack "\blog\b"

This matches only "log" as a standalone word.

How the output looks

Filenames only: ack -l "pattern". Count matches per file: ack -c "pattern". Context: ack -B 2 -A 2 "pattern" is 2 lines before and after. ack -C 3 "pattern" is 3 lines both ways. Line numbers are on by default. ack -n "pattern" makes that explicit.

The inverse

Lines that do NOT match: ack -v "pattern". Files that do NOT contain a pattern: ack -L "pattern". Super useful. Show me all files that do not have X.

File types ack already knows

Show me.

ack --perl "pattern"      # Only .pl, .pm, .t
ack --python "pattern"    # Only .py
ack --js "pattern"        # Only .js
ack --html "pattern"      # Only .html
ack --css "pattern"       # Only .css
ack --shell "pattern"     # Only .sh, .bash
ack --help-types
ack --type-set=mytype:ext:foo,bar "pattern"

Limit by filename

The -G flag takes a regex for the filename:

ack -G "\.txt$" "pattern"
ack -G "config" "pattern"
ack -G "^test" "pattern"

Options combine

ack -i -l "error"
ack -i --perl "use strict"
ack -c -G "\.log$" "ERROR"

AI-shaped searches

Show me.

ack "NUDE_CHEST|WEAPON"
ack --python "requests\.(get|post)"
ack -i "\.(png|jpg|jpeg|gif)\b"
ack "[A-Za-z0-9+/]{50,}"
ack "\d{4}-\d{2}-\d{2}"

Vision responses. Python API calls. Image references. Base64-looking blobs. Timestamps.