ACK(1)

🌸 ACK(1) 🌸

okay bestie, this is the ACK manual page πŸ’– It's section 1 (the user commands bit), from the User Contributed Perl Documentation crowd 🧚

🌸 NAME 🌸

ack - grep-like text finder ✨ ack is a grep-like text finder, and it's literally iconic πŸ’…

πŸ¦‹ SYNOPSIS πŸ¦‹

ack [options] PATTERN [FILE...]
ack -f [options] [DIRECTORY...]

πŸ’– DESCRIPTION πŸ’–

okay so ack is made for programmers, and it's giving alternative-to-grep energy πŸ”₯

ack searches the FILEs or DIRECTORYs you name for lines that match the PATTERN πŸ¦‹ By default it prints the matching lines. If you don't give it a FILE or DIRECTORY, ack searches the current directory πŸŽ€

PATTERN is a Perl regular expression 🌈 Regexes show up in plenty of other languages too, but for the exact details of how they behave, check out perlreref (<https://perldoc.perl.org/perlreref.html>). If regexes are new to you and you're curious, perlretut (<https://perldoc.perl.org/perlretut.html>) is a great place to start 🧚 And if you don't want ack to use regexes at all, look at the -Q/--literal option πŸ’œ

Ack can also list the files it would search without actually searching them πŸ‘€ That lets you use ack's file-type filtering skills without the actual search ✨


🧚 FILE SELECTION 🧚

If you don't specify files, either on the command line or piped in with the -x option, ack dives into subdirectories and picks files to search 🌸

ack is super picky (in a good way) about what it searches πŸ’… It knows about certain file types, using the file extension and, in some cases, the contents of the file. You can make these selections with the --type option πŸŽ€

With no file selection, ack searches regular files that aren't explicitly excluded by --ignore-dir and --ignore-file options, whether they're in ackrc files or on the command line πŸ¦‹

The default options ignore certain files and directories, including:

  • Backup files: files matching #*# or ending with ~.
  • Coredumps: files matching core.\d+.
  • Version control directories like .svn and .git.

Run ack with the --dump option to see what settings are set πŸ‘€

⚠️ Heads up: ack always searches the files you give it on the command line, no matter what type they are. So if you tell ack to search in a coredump, it will search in a coredump πŸ’€

πŸ‘‘ DIRECTORY SELECTION πŸ‘‘

ack goes down through the directory tree of the starting directories you specify 🌳 If you don't specify any, it uses the current working directory πŸ’– It does ignore the shadow directories many version control systems use, plus the build directories used by the Perl MakeMaker system πŸ™ˆ You can add or remove a directory from this list with the --[no]ignore-dir option. You can repeat the option to add or remove multiple directories from the ignore list ✨

For a full list of directories that don't get searched, run ack --dump 🧚


🌈 MATCHING IN A RANGE OF LINES 🌈

The --range-start and --range-end options let you pick ranges of lines to search inside each file πŸ¦‹

Say you have a file called testfile:

# This function calls print on "foo".
sub foo {
    print 'foo';
}
my $print = 1;
sub bar {
    print 'bar';
}
my $task = 'print';

Running ack print gives us five matches:

$ ack print testfile
# This function calls print on "foo".
    print 'foo';
my $print = 1;
    print 'bar';
my $task = 'print';

But what if we only want to search for "print" inside the subroutines? πŸ‘‘ We can set ranges of lines for ack to search πŸ’… A range starts at any line matching ^sub \w+ and stops at any line matching ^} ✨

$ ack --range-start='^sub \w+' --range-end='^}' print testfile
    print 'foo';
    print 'bar';

Notice that ack searched two ranges of lines πŸŽ€ The listing below shows which lines were inside a range and which were outside it:

Out # This function calls print on "foo".
In  sub foo {
In      print 'foo';
In  }
Out my $print = 1;
In  sub bar {
In      print 'bar';
In  }
Out my $task = 'print';

You don't have to set both --range-start and --range-end 🌸 If --range-start is left out, the range runs from the first line of the file until the first line matching --range-end. And if --range-end is left out, the range runs from the first line matching --range-start to the end of the file πŸ¦‹

For example, if you wanted to search all HTML files up until the first <body>, you could do:

ack foo --html --range-end='<body>'

Or, to search after Perl's __DATA__ or __END__ markers, you would do:

ack pattern --perl --range-start='^__(END|DATA)__'

It's also possible for a range to start and stop on the same line 🀯 For example:

--range-start='<title>' --range-end='</title>'

would match this line as both the start and end of the range, making a one-line range:

<title>Page title</title>

Note that the patterns in --range-start and --range-end aren't affected by options like -i, -w and -Q that change how the main pattern gets matched 🧚

Again, ranges only affect where matches are looked for πŸ’– Everything else in ack works the same way. Using the -c option with a range gives you a count of all the matches inside those ranges πŸ”’ The -l option shows the files that have a match within a range, and the -L option shows files that don't have a match within a range πŸ‘€

The -v option for negating a match works inside the range, too πŸ™Œ To see lines that don't match "google" inside the <head> section of your HTML files, you could do:

ack google -v --html --range-start='<head' --range-end='</head>'

Specifying a range doesn't change how matches are displayed πŸŽ€ The context for a match stays the same. Using the context options works the same way too, and they'll show context lines for matches even if those context lines fall outside the range ✨ Similarly, --passthru shows all lines in the file, but only shows matches for lines inside the range πŸ’…


πŸŽ€ OPTIONS πŸŽ€

  • --ackrc β€” Loads an ackrc file after all the others. Peep "ACKRC LOCATION SEMANTICS" for the deets πŸ“œ
  • --and=PATTERN β€” Says that a given PATTERN MUST ALSO be found on the line for a match to happen. You can repeat this option 🐢🐱 If you want to find all the lines with both "dogs" or "cats", use:
ack dogs --and cats

Note that the options that affect "dogs" also affect "cats" πŸ‘€ So if you have:

ack -i -w dogs --and cats

then the search for both "dogs" and "cats" will be case-insensitive and word-limited πŸ’–

--and cannot be used with --or 🚫

  • -A NUM, --after-context=NUM β€” Prints NUM lines of trailing context after matching lines 🌸
  • -B NUM, --before-context=NUM β€” Prints NUM lines of leading context before matching lines πŸ¦‹
  • --[no]break β€” Prints a break between results from different files. It's on by default when you're using ack interactively 🌈
  • -C [NUM], --context[=NUM] β€” Prints NUM lines (default 2) of context around matching lines 🧚 You can specify zero lines of context to override another context set in an ackrc πŸ™…β€β™€οΈ
  • -c, --count β€” Suppresses the normal output and prints a count of matching lines for each input file πŸ”’ If -l is in effect, it only shows the number of lines for each file that has matching lines. Without -l, some line counts may be zeroes πŸ‘€ If combined with -h (--no-filename), ack outputs only one total count ✨
  • -h, --no-filename β€” Hide the filename prefixes on output when you're searching more than one file πŸ™ˆ
  • --[no]heading β€” Prints a filename heading above each file's results πŸŽ€ This is the default when you're using ack interactively ✨
  • --help β€” Shows a short help statement πŸ’
  • --help-types β€” Prints all the known types 🧚
  • --help-colors β€” Shows a chart of various color combinations 🌈
  • --help-rgb-colors β€” Like --help-colors, but with more precise RGB colors πŸ’œ
  • -i, --ignore-case β€” Ignores case distinctions in PATTERN. Overrides --smart-case and -I. 🫢
  • -I, --no-ignore-case β€” Turns on case distinctions in PATTERN. Overrides --smart-case and -i. πŸ’…
  • --ignore-ack-defaults β€” Tells ack to totally ignore the default definitions that come with ack. This is super useful alongside --create-ackrc if you really, truly want to customize ack 🧁
  • --[no]ignore-dir=DIRNAME, --[no]ignore-directory=DIRNAME β€” Ignores a directory, just like CVS, .svn, and friends get ignored πŸ™ˆ You can use it multiple times to ignore multiple directories. For example, mason users may wish to include --ignore-dir=data. The --noignore-dir option lets you search directories that would normally be ignored (perhaps to research the contents of .svn/props directories) πŸ”
The DIRNAME must always be a simple directory name. Nested directories like foo/bar are NOT supported. You would need to specify --ignore-dir=foo and then no files from any foo directory are taken into account by ack unless given explicitly on the command line. πŸ’€
  • --ignore-file=FILTER:ARGS β€” Ignores files matching FILTER:ARGS πŸ™… The filters are set up identically to file type filters, the same way you'd see them in "Defining your own types" πŸ“–
  • -k, --known-types β€” Limits the selected files to only the types ack already knows about 🧠
  • -l, --files-with-matches β€” Only prints the filenames of matching files, instead of the matching text πŸ“„
  • -L, --files-without-matches β€” Only prints the filenames of files that do NOT match 🚫
  • --match PATTERN β€” Lets you specify the PATTERN explicitly 🎯 This is handy if you don't want the regex to be your first argument, like when you're running multiple searches over the same set of files πŸ”
# search for foo and bar in given files
ack file1 t/file* --match foo
ack file1 t/file* --match bar
  • -m=NUM, --max-count=NUM β€” Prints only NUM matches out of each file βœ‚οΈ If you want ack to stop after printing the first match of any kind, use the -1 options πŸ›‘
  • --man β€” Prints this manual page πŸ“–
  • -n, --no-recurse β€” No descending into subdirectories πŸ™…
  • --not=PATTERN β€” Specifies a PATTERN that must NOT be true on a given line for a match to happen 🚫 This option can be repeated πŸ” Want all the lines with "dogs" but not if "cats" or "fish" show up on the line? Use:
ack dogs --not cats --not fish

Heads up: the options that affect "dogs" also affect "cats" and "fish", so if you have:

ack -i -w dogs --not cats

then the search for both "dogs" and "cats" will be case-insensitive and word-limited πŸ‘€

  • -o β€” Shows only the part of each line matching PATTERN (turns off text highlighting) βœ‚οΈ This is exactly the same as --output=$&.
  • --or=PATTERN β€” Specifies a PATTERN that MAY be found on a given line for a match to happen 🀷 This option can be repeated πŸ” Want all the lines with "dogs" or "cats"? Use:
ack dogs --or cats

Heads up: the options that affect "dogs" also affect "cats", so if you have:

ack -i -w dogs --or cats

then the search for both "dogs" and "cats" will be case-insensitive and word-limited πŸ’–

"--or" cannot be used with "--and". πŸ™…
  • --output=expr β€” Outputs the evaluation of expr for each line πŸͺ„ (turns off text highlighting). If PATTERN matches more than once, a line is output for each non-overlapping match πŸ”₯

expr can contain the strings "\n", "\r", and "\t", which get expanded to their matching characters: line feed, carriage return, and tab, respectively ✨

expr can also contain the following Perl special variables πŸ‘‘

  • $1 through $9 β€” The subpattern from the matching set of capturing parentheses. If your pattern is "(.+) and (.+)" and the string is "this and that'", then $1 is "this" and $2 is "that" 🧩
  • $_ β€” The contents of the line in the file πŸ“
  • $. β€” The number of the line in the file πŸ”’
  • $&, $`, and $' β€” $& is the string matched by the pattern, $` is what precedes the match, and $' is what follows it. If the pattern is gra(ph|nd) and the string is "lexicographic", then $& is "graph", $` is "lexico", and $' is "ic" πŸ’«
  • $+ β€” The match made by the last parentheses that matched in the pattern 🎯 For example, if your pattern is "Version: (.+)|Revision: (.+)", then $+ will contain whichever set of parentheses matched.
  • $f β€” $f is available, in --output only, to insert the filename πŸ“ This is a stand-in for the discovered $filename usage in old ack2 --output, which is disallowed with ack3 for improved security πŸ”’
Use of $&, $`, and $' in your output will slow down the pattern matching 🐌

The intended usage of $f is to provide the grep or compile-error syntax needed for editor/IDE go-to-line integration, e.g. --output=$f:$.:$_ or --output=$f\t$.\t$& πŸ§‘β€πŸ’»

  • --pager=program, --nopager β€” --pager directs ack's output through program πŸ“Ί This can also be specified via the ACK_PAGER and ACK_PAGER_COLOR environment variables 🌸 Using --pager does not suppress grouping and coloring like piping output on the command line does 🎨 --nopager cancels any setting in ~/.ackrc, ACK_PAGER, or ACK_PAGER_COLOR πŸ™… No output will be sent through a pager.
  • --passthru β€” Prints all lines, whether or not they match the expression πŸ“œ Highlighting still works, though, so it can be used to highlight matches while still seeing the entire file 🌈 Like this:
# Watch a log file, and highlight a certain IP address.
$ tail -f ~/access.log | ack --passthru 123.45.67.89
  • --print0 β€” Only works in conjunction with -f, -g, -l, or -c, options that only list filenames πŸ“‹ The filenames are output separated with a null byte instead of the usual newline πŸ™Œ This is helpful when dealing with filenames that contain whitespace, e.g.:
# Remove all files of type HTML.
ack -f --html --print0 | xargs -0 rm -f
  • -p[N], --proximate[=N] β€” Groups together match lines that are within N lines of each other 🫧 This is useful for visually picking out matches that appear close to other matches πŸ‘€ For example, if you got these results without the --proximate option:
15: First match
18: Second match
19: Third match
37: Fourth match

They'd look like this with --proximate=1:

15: First match

18: Second match
19: Third match

37: Fourth match

and like this with --proximate=3:

15: First match
18: Second match
19: Third match

37: Fourth match

If N is omitted, N is set to 1 🧁

  • -P β€” Negates the effect of the --proximate option πŸ™… It's a shortcut for --proximate=0.
  • -Q, --literal β€” Quotes all metacharacters in PATTERN, so it's treated as a literal 🧷
  • -r, -R, --recurse β€” Recurses into subdirectories πŸ“‚ This is the default and is only here for compatibility with grep 🀝 You can also use it to turn --no-recurse off πŸ”„
  • --range-start=PATTERN, --range-end=PATTERN β€” Specifies patterns that mark the start and end of a range 🎒 See "MATCHING IN A RANGE OF LINES" for details πŸ“–
  • -s β€” Suppresses error messages about nonexistent or unreadable files 🀫 This one is taken from fgrep.
  • -S, --[no]smart-case, --no-smart-case β€” Ignores case in the search strings if PATTERN contains no uppercase characters 🧠 This is similar to "smartcase" in the vim text editor πŸ’š Overrides -i and -I. -S is a synonym for --smart-case. -i always overrides this option πŸ‘‘
  • --sort-files β€” Sorts the found files lexicographically πŸ”€ Use this if you want your file listings to be deterministic between runs of ack 🎯
  • --show-types β€” Outputs the filetypes that ack associates with each file 🏷️ Works with -f and -g options.
  • -t TYPE, --type=TYPE, --TYPE β€” Specifies the types of files to include in the search 🎯 TYPE is a filetype, like perl or xml. --type=perl can also be specified as --perl, although this is deprecated ⚠️ Type inclusions can be repeated and are ORed together πŸ”€ See ack --help-types for a list of valid types πŸ“œ
  • -T TYPE, --type=noTYPE, --noTYPE β€” Specifies the type of files to exclude from the search 🚫 --type=noperl can be done as --noperl, although this is deprecated. If a file is of both type "foo" and "bar", specifying both --type=foo and --type=nobar will exclude the file, because an exclusion takes precedence over an inclusion πŸ’…
  • --type-add TYPE:FILTER:ARGS β€” Files with the given ARGS applied to the given FILTER are recognized as being of (the existing) type TYPE βž• See also "Defining your own types".
  • --type-set TYPE:FILTER:ARGS β€” Files with the given ARGS applied to the given FILTER are recognized as being of type TYPE πŸ” This replaces an existing definition for type TYPE. See also "Defining your own types".
  • --type-del TYPE β€” The filters associated with TYPE are removed from Ack, and are no longer considered for searches πŸ—‘οΈ
  • --[no]underline β€” Turns on underlining of matches, where "underlining" is printing a line of carets under the match πŸ”Ί Check it out:
$ ack -u foo
peanuts.txt
17: Come kick the football you fool
                  ^^^          ^^^
623: Price per square foot
                      ^^^

This is useful if you're dumping the results of an ack run into a text file or printer that doesn't support ANSI color codes πŸ–¨οΈ The setting of underline does not affect highlighting of matches 🌈

  • -v, --invert-match β€” Invert match: selects non-matching lines πŸ™ƒ
  • --version β€” Displays version and copyright information πŸŽ‰
  • -w, --word-regexp β€” Forces PATTERN to match only whole words πŸ’―
  • -x β€” An abbreviation for --files-from=- 🫢 The list of files to search is read from standard input, with one line per file πŸ“₯

Heads up πŸ’… the list of files isn't filtered in any way with this one. If you toss --type=html in alongside -x, the --type just gets ignored, bestie πŸ™ˆ

  • -1 β€” Stops right after the first match of any kind shows up ✨ This is NOT the same as --max-count=1 or -m1, which only show one match per file. Also, -1 plays nice with -f and -g, which -m doesn't. Main character energy.
  • --thpppt β€” Shows off the all-important Bill The Cat logo 🐱 The exact spelling of --thpppppt doesn't really matter, because it gets checked against a regular expression, not an exact match πŸŽ€
  • --bar β€” Goes and checks with the admiral for traps 🧚
  • --cathy β€” A whole chocolate chant: "Chocolate, Chocolate, Chocolate!" πŸ«πŸ’œ

✨ THE .ackrc FILE ✨

The .ackrc file is basically a little stash of command-line options that get tucked in front of your command line before ack runs πŸŽ€ You can put several options across several lines, and any line starting with a # gets ignored. It might look something like this:

# Always sort the files
--sort-files

# Always color, even if piping to another program
--color

# Use "less -r" as my pager
--pager=less -r

Arguments with spaces in them don't need quotes, since the shell doesn't interpret them. Each line in the .ackrc file is interpreted as one element of @ARGV. Cute and simple 🫢

ack checks several locations for .ackrc files. The whole searching process is detailed in "ACKRC LOCATION SEMANTICS," so go read that if you're curious πŸ‘€ Also, these files get skipped entirely if --noenv is on the command line πŸ™…


✨ Defining your own types ✨

ack lets you make your own types on top of the predefined ones πŸ¦‹ The move is to put these command-line options in an .ackrc, so you never have to retype them. The examples below put options on one command line so you can copy and paste them easily.

File types can be specified with --type=xxx, or with the type itself as an option. So if you create a filetype of "cobol," you can write --type=cobol or just --cobol. File types must be at least two characters long, which is why the C language is --cc and the R language is --rr πŸ‘‘

ack --perl foo searches for foo in all perl files. ack --help-types tells you perl files are files ending in .pl, .pm, .pod or .t. Want .xs files included too? ack --type-add perl:ext:xs --perl foo does that for you. --type-add appends extra extensions to an existing type πŸ’…

Need a brand new type, or want to completely redo an existing one? Use --type-set. ack --type-set eiffel:ext:e,eiffel defines the type eiffel to include files with the extensions .e or .eiffel. To search every eiffel file for the word Bertrand, use ack --type-set eiffel:ext:e,eiffel --eiffel Bertrand. As usual, you can also write --type=eiffel instead of --eiffel. Negation works too, so --noeiffel excludes all eiffel files from a search. Redefining works as well: ack --type-set cc:ext:c,h means .xs files no longer belong to the type cc πŸ”₯

When defining your own types in the .ackrc file, you have to use one of these:

--type-set=eiffel:ext:e,eiffel

or, writing it on separate lines:

--type-set
eiffel:ext:e,eiffel
🚫 Big no no: the following does NOT work in the .ackrc file:
--type-set eiffel:ext:e,eiffel

To see all the currently defined types, use --help-types, like this: ack --type-set backup:ext:bak --type-add perl:ext:perl --help-types

ack --type-set backup:ext:bak --type-add perl:ext:perl --help-types

In addition to filtering by extension, ack offers extra filter types 🌸 The generic syntax is --type-set TYPE:FILTER:ARGS, and what ARGS looks like depends on the value of FILTER.

is:FILENAME

The is filter matches the target filename exactly. It takes exactly one argument, which is the name of the file to match.

Example:

--type-set make:is:Makefile

ext:EXTENSION[,EXTENSION2[,...]]

The ext filter matches the extension of the target file against a list of extensions. You don't need a leading dot on the extensions πŸ’–

Example:

--type-set perl:ext:pl,pm,t

match:PATTERN

The match filter checks the target filename against a regular expression. The regex is made case-insensitive for the search πŸ”

Example:

--type-set make:match:/(gnu)?makefile/

firstlinematch:PATTERN

firstlinematch checks the first line of the target file against a regular expression. Like match, the regex is made case insensitive.

Example:

--type-add perl:firstlinematch:/perl/

✨ ACK COLORS ✨

ack lets you customize the colors it uses when showing matches on screen 🌈 It uses the colors from Perl's Term::ANSIColor module, which provides the values listed below. Case doesn't matter when using these values.

There are four different colors ack uses:

  • filename
    • Option: --color-filename
    • Env. variable: ACK_COLOR_FILENAME
    • Default: bold green
  • match
    • Option: --color-match
    • Env. variable: ACK_COLOR_MATCH
    • Default: black on_yellow
  • line no.
    • Option: --color-lineno
    • Env. variable: ACK_COLOR_LINENO
    • Default: bold yellow
  • column no.
    • Option: --color-colno
    • Env. variable: ACK_COLOR_COLNO
    • Default: bold yellow

The column number one only shows up if column numbers are displayed because of the --column option πŸ¦‹

You can set colors with a command-line option, like ack --color-filename='red on_white', or with an environment variable, like ACK_COLOR_FILENAME='red on_white'. You can also put color options in your ACKRC file (see "THE .ackrc FILE") πŸŽ€

ack understands these foreground colors:

black red green yellow blue magenta cyan white

To make a background color, prepend on_ to one of the foreground colors:

on_black on_red on_green on_yellow on_blue on_magenta on_cyan on_white

Each foreground color can be modified with these attributes, which may or may not be supported by your terminal:

bold faint italic underline blink reverse concealed

You can stack any combination of modifiers onto a foreground color. If your terminal supports it, and you enjoy visual punishment, you can do something like:

ack --color-filename="blink italic underline bold red on_yellow"

For charts of the colors and what they look like, run ack --help-colors and ack --help-rgb-colors 🌈

If the eight standard colors (in their bold, faint and unmodified states) aren't enough for you, you can also specify colors by their RGB values ✨ They're written as rgbXYZ, where X, Y, and Z are values between 0 and 5 giving the intensity of red, green and blue. So rgb500 is pure red, rgb505 is purple, and so on πŸ’œ

Background colors work with the on_ prefix on an RGB color, so on_rgb505 is a purple background πŸ“

The modifier attributes like blink, italic, underscore and so on may or may not work on the RGB colors πŸ™ˆ

For a chart of the 216 possible RGB colors, run ack --help-rgb-colors 🌸


✨ ENVIRONMENT VARIABLES ✨

For commonly-used ack options, environment variables can make life way easier πŸ’… These variables get ignored if --noenv is on the command line.

  • ACKRC β€” Points to the location of the user's .ackrc file. If that file doesn't exist, ack looks in the default location.
  • ACK_COLOR_COLNO β€” The color for the column number in ack's output. By default the column number isn't shown, so you have to turn it on with the --column option. See the "ack Colors" section above.
  • ACK_COLOR_FILENAME β€” The color for the filename in ack's output. See the "ack Colors" section above.
  • ACK_COLOR_LINENO β€” The color for the line number in ack's output. See the "ack Colors" section above.
  • ACK_COLOR_MATCH β€” The color for the matched text in ack's output. See the "ack Colors" section above.
  • ACK_PAGER β€” Specifies a pager program, like "more," "less" or "most," that ack sends its output to. Using ACK_PAGER doesn't suppress grouping and coloring the way piping on the command line does, except that on Windows ack assumes ACK_PAGER doesn't support color. ACK_PAGER_COLOR overrides ACK_PAGER if both are specified.
  • ACK_PAGER_COLOR β€” Specifies a pager program that understands ANSI color sequences. Using ACK_PAGER_COLOR doesn't suppress grouping and coloring the way piping on the command line does. If you're not on Windows, you never need to use ACK_PAGER_COLOR. 🫢

✨ ACK & OTHER TOOLS ✨

Simple vim integration

ack plays nicely with Vim πŸ’œ Set this in your .vimrc to use ack instead of grep:

set grepprg=ack\ -k

That example uses -k to search through only the files of the types ack knows about, but you can use other default flags too. Now you can search with ack and easily step through the results in Vim:

:grep Dumper perllib

Editor integration

Lots of users have hooked ack up to their favorite text editors πŸ¦‹ For details and links, see https://beyondgrep.com/more-tools/.

Shell and Return Code

For greater compatibility with grep, ack in normal use returns a shell return code (exit code) of 0 only if something is found, and 1 if no match is found 🌈

(Shell exit code 1 is $?=256 in perl with system or backticks.)

The grep code 2 for errors is not used πŸ™…

If -f or -g are specified, then 0 is returned if at least one file is found. If no files are found, then 1 is returned.


✨ DEBUGGING ACK PROBLEMS ✨

If ack gives you output you're not expecting, don't panic, just start with a few simple steps πŸ”

Try it with --noenv

Your environment variables and .ackrc may be doing things you're not expecting, or things you forgot you specified πŸ™ˆ Use --noenv to ignore your environment and .ackrc.

Use -f to see what files have been selected for searching

Ack's -f was originally added as a debugging tool 🧚 If ack isn't finding matches you think it should find, run ack -f to see what files have been selected. You can also add the --show-types option to show the type of each file selected.

Use --dump

This lists the ackrc files that are loaded and the options loaded from them. You might be loading an .ackrc file you didn't even know you were loading πŸ‘€

✨ ACKRC LOCATION SEMANTICS ✨

Okay bestie, ack can grab its settings from a bunch of different places πŸ—ΊοΈπŸ«Ά. Each one that exists gets loaded in this exact order, and every later one overrides what the earlier ones set. Like, if I set --sort-files in my user ackrc but type --nosort-files on the command line, the command line wins. Main character energy πŸ‘‘

  • Defaults: ack starts with the defaults from App::Ack::ConfigDefaults. You can skip those with --ignore-ack-defaults πŸ’…
  • Global ackrc: next up is the global ackrc, which lives at /etc/ackrc on Unix-like systems 🌸
    • Windows XP and earlier: C:\Documents and Settings\All Users\Application Data\ackrc
    • Windows Vista/7: C:\ProgramData\ackrc
    • The --noenv option stops every ackrc file from loading πŸ™ˆ
  • User ackrc: then your own ackrc, at $HOME/.ackrc on Unix-like systems πŸ¦‹
    • Windows XP and earlier: C:\Documents and Settings\$USER\Application Data\ackrc
    • Windows Vista/7: C:\Users\$USER\AppData\Roaming\ackrc
    • Want a different user-level ackrc? Point the $ACKRC environment variable at it ✨
    • The --noenv option stops every ackrc file from loading πŸ™ˆ
  • Project ackrc: then the project ackrc, which is the first file named .ackrc or _ackrc that ack finds. It checks the current directory first, then the parent directory, then the grandparent, and so on 🧚 You can skip this one with --noenv.
  • --ackrc: the --ackrc option on the command line can name an ackrc file that overrides all the others. It still gets consulted even when --noenv is there πŸ‘‘
  • Command line: last but not least, options from the command line get loaded πŸ’–

✨ BUGS & ENHANCEMENTS ✨

Bugs happen to the best of us, so don't stress. ack lives on GitHub at https://github.com/beyondgrep/ack3 πŸ›

Report bugs or request features on the issues list at https://github.com/beyondgrep/ack3/issues. Please include the operating system you're on, the output of ack --version, and any customizations in your .ackrc 🫢

Wanna suggest an enhancement? Submit an issue at https://github.com/beyondgrep/ack3/issues. Also read the DEVELOPERS.md file in the ack code repository πŸ’…

Want to chat about your issues? Hop on the ack mailing list at https://groups.google.com/group/ack-users πŸ’¬

✨ SUPPORT ✨

Support and info for ack live in all these spots 🌈

✨ COMMUNITY ✨

There are ack mailing lists and a Slack channel for ack 🫧 Check https://beyondgrep.com/community/ for all the details πŸŽ€

✨ FAQ ✨

Frequently asked questions, bestie, let's gooo 🧚

πŸ™ˆ Can I stop using grep now?

Many people find ack better than grep as an everyday tool 99% of the time, but don't throw grep away! There are times you'll still need it. For example, you might be digging through huge log files without using regular expressions. In that case, grep will probably perform better πŸ’€

πŸ” Why isn't ack finding a match in (some file)?

First, check whether ack is even looking at the file. ack is smart about which files it searches and which ones it skips, but sometimes that can be surprising πŸ‘€

Use the -f switch, with no regex, to see a list of the files ack will search for you. If your file doesn't show up in that list, then ack never looks in it 🫢

πŸ’… Wouldn't it be great if ack did search & replace?

No, ack will always be read-only. Perl already has a perfectly good way to do search & replace in files, using the -i, -p and -n switches ✨

You can still use ack to pick out the files you want to update. For example, to change all "foo" to "bar" in all PHP files, you can do this from the Unix shell:

$ perl -i -p -e's/foo/bar/g' $(ack -f --php)

🧩 Can I make ack recognize .xyz files?

Yes! Please check out "Defining your own types" in the ack manual πŸŽ€

🌈 Will you make ack recognize .xyz files by default?

We might, depending on how widely used the file format is 🀷

Submit an issue in the GitHub issue queue at https://github.com/beyondgrep/ack3/issues. Explain what the file format is, where we can find out more about it, and what you've been using in your .ackrc to support it πŸ’–

Please do not bother creating a pull request. The code for filetypes is trivial compared to the rest of the process we go through πŸ™ƒ

πŸŽ€ Why is it called ack if it's called ack-grep?

The program's name is "ack". Some packagers have called it "ack-grep" when making packages, because there's already a package out there called "ack" that has nothing to do with this ack 😭

I suggest you make a symlink named ack that points to ack-grep, because one of the crucial benefits of ack is having a name that's so short and simple to type ⭐ To do that, run this with sudo or as root:

ln -s /usr/bin/ack-grep /usr/bin/ack

Alternatively, you could use a shell alias:

# bash/zsh
alias ack=ack-grep

# csh
alias ack ack-grep

🀷 What does ack mean?

Nothing! I wanted a name that was easy to type and that you could pronounce as a single syllable πŸ“

🚫 Can I do multi-line regexes?

No, ack does not support regexes that match multiple lines. Doing that would mean reading in the entire file at a time πŸ™…

If you want to see lines near your match, use the --A, --B and --C switches for displaying context πŸ¦‹

βž• Why is ack telling me I have an invalid option when searching for "+foo"?

ack treats command line options beginning with + or - as options. If you want to search for these, you can prefix your search term with -- or use the --match option. (But don't forget that + is a regex metacharacter!) 🧠

πŸ”’ Why does ack '.{40000,}' fail? Isn't that a valid regex?

Perl limits the repetition quantifier to 32K. You can search for .{32767} but not .{32768} πŸ“

🧐 Ack does "X" and shouldn't, should it?

We try to stay as close to grep's behavior as possible, so when in doubt, see what grep does! If there's a mismatch in functionality, please submit an issue to GitHub, and/or bring it up on the ack-users mailing list 🫢

✨ ACKNOWLEDGEMENTS ✨

How appropriate to have acknowledgements! πŸ₯ΉπŸ’– Thanks to everyone who has contributed to ack in any way, including Dmitri Vereshchagin, Geraint Edwards, Loren Howard, Yaroslav Halchenko, Thiago Perrotta, Thomas Gossler, Kieran Mace, Volker Glave, Axel Beckert, Eric Pement, Gabor Szabo, Frieder Bluemle, Grzegorz Kaczmarczyk, Dan Book, Tomasz Konojacki, Salomon Smeke, M. Scott Ford, Anders Eriksson, H.Merijn Brand, Duke Leto, Gerhard Poul, Ethan Mallove, Marek Kubica, Ray Donnelly, Nikolaj Schumacher, Ed Avis, Nick Morrott, Austin Chamberlin, Varadinsky, SΓ©bastien FeugΓ¨re, Jakub Wilk, Pete Houston, Stephen Thirlwall, Jonah Bishop, Chris Rebert, Denis Howe, RaΓΊl GundΓ­n, James McCoy, Daniel Perrett, Steven Lee, Jonathan Perret, Fraser Tweedale, RaΓ‘l GundΓ‘n, Steffen Jaeckel, Stephan Hohe, Michael Beijen, Alexandr Ciornii, Christian Walde, Charles Lee, Joe McMahon, John Warwick, David Steinbrunner, Kara Martens, Volodymyr Medvid, Ron Savage, Konrad Borowski, Dale Sedivic, Michael McClimon, Andrew Black, Ralph Bodenner, Shaun Patterson, Ryan Olson, Shlomi Fish, Karen Etheridge, Olivier Mengue, Matthew Wild, Scott Kyle, Nick Hooey, Bo Borgerson, Mark Szymanski, Marq Schneider, Packy Anderson, JR Boyens, Dan Sully, Ryan Niebur, Kent Fredric, Mike Morearty, Ingmar Vanhassel, Eric Van Dewoestine, Sitaram Chamarty, Adam James, Richard Carlsson, Pedro Melo, AJ Schuster, Phil Jackson, Michael Schwern, Jan Dubois, Christopher J. Madsen, Matthew Wickline, David Dyck, Jason Porritt, Jjgod Jiang, Thomas Klausner, Uri Guttman, Peter Lewis, Kevin Riggle, Ori Avtalion, Torsten Blix, Nigel Metheringham, GΓ‘bor SzabΓ³, Tod Hagan, Michael Hendricks, Γ†var ArnfjΓΆrΓ° Bjarmason, Piers Cawley, Stephen Steneker, Elias Lutfallah, Mark Leighton Fisher, Matt Diephouse, Christian Jaeger, Bill Sully, Bill Ricker, David Golden, Nilson Santos F. Jr, Elliot Shank, Merijn Broeren, Uwe Voelker, Rick Scott, Ask BjΓΈrn Hansen, Jerry Gay, Will Coleda, Mike O'Regan, Slaven ReziΔ‡, Mark Stosberg, David Alan Pisoni, Adriano Ferreira, James Keenan, Leland Johnson, Ricardo Signes, Pete Krawczyk and Rob Hoelz 🫢✨

✨ AUTHOR ✨

Andy Lester, "<andy at petdance.com>" πŸ‘‘

Copyright 2005-2026 Andy Lester 🌸

This program is free software; you can redistribute it and/or modify it under the terms of the Artistic License v2.0 πŸ’œ

See https://www.perlfoundation.org/artistic-license-20.html or the LICENSE.md file that comes with the ack distribution πŸ¦‹


And that's the whole page, bestie! πŸ’– Made from perl v5.42.2 and dated 2026-06-07, so you know it's fresh πŸŽ€ Now go ack something iconic πŸ’…βœ¨

πŸ“¦ where this page comes from