Skip to content

Commit f57d897

Browse files
nasanosSachin-Sureshandystevensname
authored
Guide on the ack command (linode#5494)
* Initial draft of the guide on the ack command. * tech edit * copy edit and merge develop --------- Co-authored-by: Sachin-Suresh <Sachin301190@gmail.com> Co-authored-by: Andy Stevens <taylorstevens@gmail.com>
1 parent 671162f commit f57d897

File tree

3 files changed

+356
-0
lines changed

3 files changed

+356
-0
lines changed

.hugo_build.lock

Whitespace-only changes.

ci/vale/dictionary.txt

+4
Original file line numberDiff line numberDiff line change
@@ -1589,6 +1589,8 @@ perceptron
15891589
percona
15901590
performant
15911591
perl
1592+
perlre
1593+
perldoc
15921594
permalink
15931595
permalinks
15941596
Petazzoni
@@ -1977,6 +1979,7 @@ shotcut
19771979
shoutcast
19781980
scikit
19791981
scribus
1982+
scrollable
19801983
sidekiq
19811984
sievers
19821985
signup
@@ -2392,6 +2395,7 @@ wasn
23922395
wasm
23932396
wav
23942397
wazuh
2398+
wc
23952399
wchar
23962400
wchar_t
23972401
webadmin
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
---
2+
slug: how-to-use-ack-command
3+
description: "The ack command provides a powerful alternative to grep. The ack command has the benefit of being specifically designed for working with source code repositories, making it a more well-suited tool for developers. In this tutorial, learn everything you need to get started using it."
4+
keywords: ['ack command line', 'ack command in linux', 'ack command examples']
5+
tags: ['linux']
6+
license: '[CC BY-ND 4.0](https://creativecommons.org/licenses/by-nd/4.0)'
7+
published: 2023-03-20
8+
modified_by:
9+
name: Nathaniel Stickman
10+
title: "How to Use the ack Command on Linux"
11+
title_meta: "Using the ack Command on Linux"
12+
external_resources:
13+
- '[ack!: Documentation](https://beyondgrep.com/documentation/)'
14+
- '[DigitalOcean: How To Install and Use Ack, a Grep Replacement for Developers, on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-ack-a-grep-replacement-for-developers-on-ubuntu-14-04)'
15+
- '[Linux Shell Tips: How to Install and Use Ack Command in Linux with Examples](https://www.linuxshelltips.com/ack-command-in-linux/)'
16+
authors: ["Nathaniel Stickman"]
17+
---
18+
19+
The Linux search tool *grep* has plenty to offer, but, if you are working with source code, there is a more efficient alternative. That alternative is *ack*, a faster tool dedicated specifically to searching source code.
20+
21+
*ack* boasts an increased performance by identifying relevant files and searching only those. *ack* also brings in optimized regular expressions, meant to make pattern matching more efficient.
22+
23+
This guide helps introduce you to *ack* and everything it has to offer. It covers everything from the basics that many *grep* users are familiar with to more advanced searches using regular expressions and file-type filters.
24+
25+
## Before You Begin
26+
27+
1. Familiarize yourself with our [Getting Started with Linode](/docs/getting-started/) guide and complete the steps for setting your Linode's hostname and timezone.
28+
29+
1. This guide uses `sudo` wherever possible. Complete the sections of our [How to Secure Your Server](/docs/security/securing-your-server/) guide to create a standard user account, harden SSH access, and remove unnecessary network services.
30+
31+
1. Update your system.
32+
33+
- On **Debian** and **Ubuntu**, use the following command:
34+
35+
```command
36+
sudo apt update && sudo apt upgrade
37+
```
38+
39+
- On **AlmaLinux**, **CentOS** (8 or later), or **Fedora**, use the following command:
40+
41+
```command
42+
sudo dnf upgrade
43+
```
44+
45+
{{< note >}}
46+
The steps in this guide are written for non-root users. Commands that require elevated privileges are prefixed with `sudo`. If you’re not familiar with the `sudo` command, see the [Linux Users and Groups](/docs/tools-reference/linux-users-and-groups/) guide.
47+
{{< /note >}}
48+
49+
## ack vs grep: Which One to Use?
50+
51+
Both *ack* and *grep* are command-line search tools, capable of matching string patterns to find text within files and directories.
52+
53+
The main difference between the two is emphasis. The *grep* command is considered a standard, helped by the fact that it comes installed by default on most Linux systems. It is a general-purpose tool, meant to be versatile enough for any kind of search but not specifically optimized for any kind in particular.
54+
55+
Meanwhile, the *ack* command aims for higher efficiency by applying itself to searching particular kinds of files, those found in source code repositories. Because it is designed with this particular use in mind, *ack* can ignore certain files as irrelevant. Doing so makes its searches easier for users to navigate and more performant compared to *grep*.
56+
57+
In general, *grep* still offers much when it comes to general-purpose text searches. But, if you are specifically looking for a tool for searching within source code repositories, *ack* should be your go-to command-line tool.
58+
59+
## How to Install the ack Command
60+
61+
Installing *ack* is straightforward using your Linux system's package manager.
62+
63+
- On **Debian** and **Ubuntu**, use the following command:
64+
65+
```command
66+
sudo apt install ack
67+
```
68+
69+
However, on **Debian** 9 or older or **Ubuntu** 19.10 or older, you should use the following command instead:
70+
71+
```command
72+
sudo apt install ack-grep
73+
```
74+
75+
- On **AlmaLinux**, **CentOS**, and **Fedora**, use the following command:
76+
77+
```command
78+
sudo dnf install ack
79+
```
80+
81+
You can verify your installation by checking the installed *ack* version. The output varies depending on your Linux system, but the command should look something like the below:
82+
83+
```command
84+
ack --version
85+
```
86+
87+
```output
88+
ack 2.24
89+
Running under Perl 5.28.1 at /usr/bin/perl
90+
91+
Copyright 2005-2018 Andy Lester.
92+
93+
This program is free software. You may modify or distribute it
94+
under the terms of the Artistic License v2.0.
95+
```
96+
97+
## How to Search Source Code with the ack Command
98+
99+
These next sections walk you through how to start using *ack* to search source code repositories.
100+
101+
To see *ack* in action, the examples that follow use the source code for the [Terrastories](https://github.com/Terrastories/terrastories) project. You can download the repository to follow along with the examples using the steps below:
102+
103+
1. Ensure that you have Git installed. The repository, like many other open-source code repositories, is stored using Git.
104+
105+
- On **Debian** and **Ubuntu**, you can install Git using the following command:
106+
107+
```command
108+
sudo apt install git
109+
```
110+
111+
- On **AlmaLinux**, **CentOS**, and **Fedora**, you can install Git using the following command:
112+
113+
```command
114+
sudo dnf install git
115+
```
116+
117+
1. Clone the GitHub repository for the project. Here, the repository is cloned into the current user's home directory. A project subdirectory is automatically created:
118+
119+
```command
120+
cd ~
121+
git clone https://github.com/Terrastories/terrastories
122+
```
123+
124+
1. Change into the project's directory.
125+
126+
```command
127+
cd terrastories
128+
```
129+
130+
Additionally, most guides recommend that you configure *ack* to pipe long-listed results into *less*. The *less* program, generally installed by default on Linux systems, can make output conveniently scrollable.
131+
132+
You can implement this configuration change with a single command. The command writes a line to the *ack* configuration file telling it to pipe long output:
133+
134+
```command
135+
echo '--pager=less -RFX' >> ~/.ackrc
136+
```
137+
138+
### Get Count of Files
139+
140+
A basic usage of *ack* is simply getting a count of the relevant files in a source code directory. You can achieve this using the following command:
141+
142+
```command
143+
ack -f | wc -l
144+
```
145+
146+
```output
147+
667
148+
```
149+
150+
Here, the *ack* command runs with the `-f` option. This tells *ack* to identify all relevant files in the repository, without any search pattern. The results are piped into *wc*, which, with the `-l` option, counts the number of lines of output.
151+
152+
It is important to note that *ack* only queries the files it deems relevant. Remember, *ack* is designed for searching source code specifically, not searching files generally. So, its elimination of certain files from searches is intended to make it more efficient than *grep* for its particular use case.
153+
154+
To demonstrate, compare the file count from *ack* to the standard way of getting file counts on Linux using the *find* command:
155+
156+
```command
157+
find . | wc -l
158+
```
159+
160+
```output
161+
933
162+
```
163+
164+
### Search by Term
165+
166+
Of course, most often you want to search files by a given term or set of terms. You can achieve this by giving the `ack` command your search pattern, as shown below:
167+
168+
```command
169+
ack create
170+
```
171+
172+
```output
173+
README.md
174+
91:Push your branch up and create a pull request! Please indicate which issue your PR addresses in the title.
175+
176+
documentation/SETUP-LINUX.md
177+
33:Copy the contents of this file into a newly created file called `.env` (Do not change .env.example!).
178+
35:Now navigate to a site called [Mapbox](https://mapbox.com/signup) create an account and copy the Mapbox access token (either your default public token or a new one you create) found under your account.
179+
37:Navigate back to the `.env` file you created and replace where it says [your pk token here] with your Mapbox access token.
180+
[...]
181+
```
182+
183+
The above command finds even partial matches for the search term. For example, though the search term is `create`, the results include lines with `created`.
184+
185+
Additionally, the example above is case-sensitive. This means that while all cases of `create`, `created`, etc. can be found, cases of `Create`, `Created`, etc., are not.
186+
187+
You can adjust both of those factors, however. In this next example, the `-w` option tells *ack* to find only whole-word matches — that is, `create` but not `created`. The `-i` option tells *ack* to make the search case-insensitive, so it can return results of `create` and `Create`:
188+
189+
```command
190+
ack -i -w create
191+
```
192+
193+
```output
194+
.github/ISSUE_TEMPLATE/bug_report.md
195+
3:about: Create a report to help us improve
196+
197+
.github/ISSUE_TEMPLATE/feature_request.md
198+
20:- [ ] \(Optional) Create an integration test for any new feature
199+
200+
README.md
201+
84:**Step 4: Create a branch**
202+
91:Push your branch up and create a pull request! Please indicate which issue your PR addresses in the title.
203+
```
204+
205+
#### Advanced Searches with Regex
206+
207+
The pattern field for *ack* searches also supports regular expressions (regex). Regex provides a pattern-matching syntax for searching and sometimes replacing, text. It is often used for advanced pattern matching and can be a powerful tool for demanding search tasks.
208+
209+
Here is a straightforward example of regex in *ack*. The pattern allows *ack* to find lines matching two search terms. For this example, the terms must be set off by spaces to match, and they can be separated by any number and variation of characters:
210+
211+
```command
212+
ack -i ' create (.*) example '
213+
```
214+
215+
```output
216+
documentation/SETUP-OFFLINE.md
217+
58:*Raster tiles*: If you have raster tiles that you want to load in Terrastories, those will need to be defined differently from the vector tiles above. In `sources`, create a new source definition with `url` pointing to the raster `MBTIles` in the same format as above, `type` set to `raster`, and `tileSize` to `256`. Then, in `layers`, create a map object with your `id` of choice, `type` set to `raster`, and `source` set to the name of your raster tiles as defined in `sources`. Here is an example:
218+
219+
rails/db/seeds.rb
220+
17:# Create an example Community
221+
95:# Create an admin user for example community
222+
103:# Create an editor user for example community
223+
111:# Create a member user for example community
224+
119:# Create a viewer user for example community
225+
```
226+
227+
*ack* uses the Perl implementation of regular expression syntax, also known as *Perlre*. The full reference for this regex syntax can be found in the [official Perldoc documentation](https://perldoc.perl.org/perlre).
228+
229+
However, that reference can be daunting, especially when starting out with regex. You may, instead, find the coverage of regex filters in our [How to Filter Data Using AWK RegEx](/docs/guides/filter-data-using-awk-regex/) more helpful to start with. The guide does not specifically address Perl regex. Nonetheless, it provides useful examples and breakdowns to help you get a footing with regex's usage and capabilities generally.
230+
231+
#### Count Matches per File
232+
233+
The *ack* command also includes several options for counting matches. Using the *wc* program like above can give you a count of files, but the options built into *ack* give you more granular control and can count the number of matches.
234+
235+
These options all build on the `-c` option. This option causes *ack* to list file names with the number of matches in each file. For instance, this command lists files and indicates the number of times each has the term `def`:
236+
237+
```command
238+
ack -c def
239+
```
240+
241+
```output
242+
[...]
243+
documentation/CODE_OF_CONDUCT.md:0
244+
documentation/CUSTOMIZATION.md:2
245+
.gitattributes:0
246+
rails/.gitignore:2
247+
rails/db/migrate/20200425195232_rename_curriculum_stories_order_to_display_order.rb:1
248+
rails/db/migrate/20220414120430_add_mapbox_3d_boolean.rb:2
249+
[...]
250+
```
251+
252+
Notice, however, that these results include files without any matches for the term. The full results include many such files.
253+
254+
To weed these out, you can add the `-l` option alongside the `-c` option. The `-l` option instructs *ack* to only list files that have at least one match to the search pattern:
255+
256+
```command
257+
ack -cl def
258+
```
259+
260+
```output
261+
[...]
262+
documentation/CUSTOMIZATION.md:2
263+
rails/.gitignore:2
264+
rails/db/migrate/20200425195232_rename_curriculum_stories_order_to_display_order.rb:1
265+
rails/db/migrate/20220414120430_add_mapbox_3d_boolean.rb:2
266+
rails/db/migrate/20210323183008_add_map_config_to_theme.rb:1
267+
rails/db/migrate/20201213191300_add_super_admin_to_users.rb:2
268+
[...]
269+
```
270+
271+
Finally, you may want a pure count of matches, without the list of file names. You can get this by adding the `-h` option. This option removes the display of file names. Combined with the `-c` option, it results in a simple count of matches within the repository, like this:
272+
273+
```command
274+
ack -ch def
275+
```
276+
277+
```output
278+
568
279+
```
280+
281+
### Limit Searches by File Type
282+
283+
The *ack* tool is oriented around source code repositories, and many times it can be useful to limit searches in these repositories by file type. As such, *ack* includes a wide set of options designed for filtering searches based on file types.
284+
285+
To use these options, you can provide the file-type name as a flag on the *ack* command. This example, for instance, searches the repository for the term `blue` but has _ack_ only looks at SASS files (which end in either `.sass` or `.scss`):
286+
287+
```command
288+
ack --sass blue
289+
```
290+
291+
```output
292+
rails/app/assets/stylesheets/core/_colors.scss
293+
29:$blue: #09697e;
294+
30:$light-blue: #179caa;
295+
31:$medium-blue: $blue;
296+
32:$dark-blue: #0f566b; // does not match palatte since dark blue is text color
297+
298+
rails/app/assets/stylesheets/components/devise.scss
299+
36: color: $blue;
300+
92: background-color: $blue;
301+
302+
rails/app/assets/stylesheets/components/card.scss
303+
75: background: $dark-blue;
304+
92: background-color: $dark-blue;
305+
145: border: 3px solid $dark-blue;
306+
[...]
307+
```
308+
309+
Conversely, you can use a similar approach to exclude a given file type. These works are simply adding `no` to the beginning of the file-type name, as in:
310+
311+
```command
312+
ack -w --nosass red
313+
```
314+
315+
```output
316+
rails/yarn.lock
317+
3506: functional-red-black-tree "^1.0.1"
318+
4137:functional-red-black-tree@^1.0.1:
319+
4139: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
320+
[...]
321+
```
322+
323+
You can even fine-tune your searches further by using multiple file-type flags at the same time.
324+
325+
To see a full list of supported file types in *ack*, you can run the command with the `--help-types` option, as in:
326+
327+
```command
328+
ack --help-types
329+
```
330+
331+
```output
332+
[...]
333+
The following is the list of file types supported by ack. You can
334+
specify a file type with the --type=TYPE format, or the --TYPE
335+
format. For example, both --type=perl and --perl work.
336+
337+
Note that some extensions may appear in multiple types. For example,
338+
.pod files are both Perl and Parrot.
339+
340+
--[no]actionscript .as .mxml
341+
--[no]ada .ada .adb .ads
342+
--[no]asm .asm .s
343+
[...]
344+
```
345+
346+
## Conclusion
347+
348+
That covers everything you need to start using the *ack* command-line tool on your Linux system.
349+
350+
When it comes to text searches in source code repositories, *ack* gives you an efficient and streamlined alternative to the *grep* standard. And, with all the features covered in this tutorial, you should be ready to put *ack* to practical use.
351+
352+
Have more questions or want some help getting started? Feel free to reach out to our [Support](https://www.linode.com/support/) team.

0 commit comments

Comments
 (0)