{"id":20134583,"url":"https://github.com/gnebbia/ack_tutorial","last_synced_at":"2025-06-12T02:35:43.445Z","repository":{"id":129497988,"uuid":"147682436","full_name":"gnebbia/ack_tutorial","owner":"gnebbia","description":"A small personal reference to ack with many examples","archived":false,"fork":false,"pushed_at":"2021-08-02T08:25:10.000Z","size":26,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-13T09:27:32.000Z","etag":null,"topics":["ack","examples","guide","perl","tutorial"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gnebbia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-06T14:01:26.000Z","updated_at":"2022-06-07T08:09:59.000Z","dependencies_parsed_at":"2023-05-22T23:31:03.048Z","dependency_job_id":null,"html_url":"https://github.com/gnebbia/ack_tutorial","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnebbia%2Fack_tutorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnebbia%2Fack_tutorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnebbia%2Fack_tutorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnebbia%2Fack_tutorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gnebbia","download_url":"https://codeload.github.com/gnebbia/ack_tutorial/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241581160,"owners_count":19985707,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ack","examples","guide","perl","tutorial"],"created_at":"2024-11-13T21:10:06.272Z","updated_at":"2025-03-02T22:28:07.722Z","avatar_url":"https://github.com/gnebbia.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ack Tutorial\n\nAck is a very flexible utility which can be used to perform searches inside\nsource code, plenty of programmers are tempted of using grep for doing this, but\nas we will see, ack provides a much more flexible alternative to the classical grep in coding\nscenarios.\nThis tutorial collects typical usage scenarios of ack, notice that ack is\ndeveloped in Perl, and a faster although not so flexible version written in C is\n'ag', if something faster is needed, just check it out.\n\n\n```sh\nack 'pattern'\n# searches for that pattern in all files starting from current directory and all\n# its subdirectories except .svn and .git\n```\n\n```sh\nack 'pattern' path/to/dir\n# searches for that pattern in all files starting from specified  directory and all\n# its subdirectories except .svn and .git by default\n```\n\n```sh\nack 'pattern' -w \n# uses word boundaries, in order to not match pattern within another string\n```\n\n```sh\nack 'pattern' --ignore-dir env/ --ignore-dir dataset/\n# searches for pattern but ignores everything inside the specified directories\n```\n\n```sh\nack 'pattern' --ignore-file=ext:pod,t,py,csv,tsc\n# searches for pattern but ignores all the files who have the specified\n# extensions\n```\n\n```sh\nack 'pattern' --ignore-file=match:/^#.+#$/\n# searches for pattern but ignores all the files who match the specified regular\n# expression\n```\n\n```sh\nack 'pattern' -l \n# only prints the file names containing the pattern\n```\n\n\n```sh\nack 'pattern' -L \n# only prints the file names NOT containing the pattern\n```\n\n\n```sh\nack 'pattern' -g \n# only prints file names matching either base name or absolute path \n# with pattern\n```\n\n```sh\nack -g log --ruby\n# prints all the files which have in their path/name the specified pattern\n# and or of type ruby\n```\n\n```sh\nack -g log --noruby\n# prints all the file which have in their path/name the specified pattern\n# but do not belong to the ruby type, remember that an ack --dump\n# also helps us inspecting various types\n```\n\n```sh\nack pattern -n\n# only searches in current directory without going into subdirectories\n```\n\n```sh\nack file1 --match foo\n# the --match option allows us to defer the specification of the match\n# so that it is not the first given parameter\n```\n\n```sh\nack pattern --pager=less\n# allows the view of the results through a pager without suppressing colors and\n# syntax highlighting\n```\n\n```sh\nack pattern -i \n# search for pattern ignoring case\n```\n\n```sh\nack -Q pattern \n# search for pattern doing a literal search, like fgrep, so we do not take into\n# account regexes\n```\n\n```sh\nack -Q aa.bb.cc.dd /path/to/access.log\n# search for pattern doing a literal search, like fgrep, so we do not take into\n# account regexes metacharacters\n```\n\n\n```sh\nack --help=types\n# shows help in order to do search with respect to file types,\n```\n\nNow if from type we see that in order to search for .sh and .ksh files\nwe have to specify `--bash` or `--nobash` we can include that in our searches for\nexample:\n\n```sh\nack pattern --nobash\n```\n\nlet's see a more complicated example:\n```sh\nack pattern --nopython  --ignore-dir env/ --pager=less\n```\n\n```sh\nack -f --python\n# prints all the filenames of type 'python'\n# this can be useful for debugging purposes especially\n# when we define our own types\n```\n\n\n```sh\nack pattern -v \n# works like in grep, will make the negation of the pattern and search for lines\n# not containing that pattern\n```\n\n\n\n```sh\nack --match 'clone.*deep|deep.*clone'  --nopython  --ignore-dir env/ --pager=less\n# searches all the files which are not python and not in the env/ directory and\n# who have on the same line either the sequence clone \u003csommething\u003e deep or \n# deep \u003csomething\u003e clone\n```\n\n\n```sh\nack -l pattern2 $(ack -l pattern1)\n# files that contains pattern1 and also contain pattern2, even if they are on\n# different lines.\n```\n\n\n```sh\nack pattern -C 4\n# gives 4 lines of context around matching lines\n```\n\n```sh\nack pattern -B 4\n# gives 4 lines of context around matching lines\n# taking lines before the matching line\n```\n```sh\nack pattern -A 4\n# gives 4 lines of context around matching lines\n# taking lines after the matching line\n```\n\n```sh\nack pattern -c \n# prints out for each file the number of matches for the specified pattern\n# if also -l is active it will only show the number of matchine lines for\n# files which are matching\n```\n\n\n```sh\nack pattern -ch \n# prints out for each file the number of matches for the specified pattern\n# with the -h option active, we suppress the filenames and only get a total\n# sum of matches\n```\n\n```sh\nack pattern -ch -w --python \n# print the number of matches for the word `pattern` in all python files\n```\n\n```sh\nack pattern --files-from=filelist.txt\n# searches the pattern only in the files specified in the mentioned file\n```\n\n\n```sh\nack --dump\n# prints all the current configuration with which ack is running,\n# this is very useful for debugging purposes but also to understand\n# how certain options have to be set or how a type of file is defined\n```\n\n## Modifying output after search\n\nWe can specify output options for our searches, for example, let's say we want\nto wrap all the words containing the letter 'e' around underscores, we can do\nsomething like:\n\n```sh\nack2.pl \"\\w*e\\w*\" quick.txt --output=\"$`_$\u0026_$'\"\n```\n\nwith the `--output` option we have special expansion strings which are:\n\n* `$\u0026` The whole string matched by PATTERN.\n* `$1, $2, ... ` The contents of the 1st, 2nd ... bracketed groups in PATTERN\n* `$\\`` The string before the match\n* `$'` The string after the match\n\n\n\n## Using ack like grep\n\nWe generally can substitute grep with ack in many cases, let's see some\nexamples:\n\n```sh\nack 'type \\w+' README.md -oh\n# outputs only the text matching the specified pattern, this is very\n# useful especially when we want to extract text or remove text from a file\n# or more files\n```\n\n```sh\nack 'classifier \\w+' ML_NOTES -c\n# counts the occurrences of the specified pattern\n```\n\n```sh\nack 'classifier \\w+' ML_NOTES -i\n# performs a case-insensitive search of the pattern\n```\n\nNotice that the position of the flags is not important, we can also put those\njust after 'ack'.\n\n\n## Define a new Type\n\n```sh\nack pattern --type-add=cpp:ext:cpp,cc,cxx,m,hpp,hh,h,hxx --cpp\n# here we are defining a file type called cpp with the supported extensions\n# being cpp,cc,cxx,hpp,hh,h,hxx\n# this is just used as a demo example, since this type already exists by default\n# in ack then we search for these files using the mentioned pattern\n```\n\n\nWe can also define types by inspecting the first line of the file, this is\nuseful for example for types of files who use shebang notation `#!` and so on,\nlet's see an example:\n\n```sh\nack pattern --type-add=sctv:firstlinematch:/^sctv/ --sctv\n# here we are defining a file type called sctv which is characterized by files\n# having as a first line starting with the string sctv\n# then we search for these files using the mentioned pattern\n```\n\n## Changing Ack configuration\n\nBy default Ack tries to read `~/.ackrc` and `.ackrc` in the current directory \nas the default configuration files, if these do not exist it still has a\ndefault configuration.  We can change Ack configuration by first printing \nits current default configuration on the standard output and saving it \nto a file.\n\nWe can do this by issuing:\n```sh\nack --create-ackrc \u003e .ackrc\n# saves to a file current ackrc configuration\n```\n\nand then by editing the `.ackrc` as we wish. \nSo for example by defining our own types or telling ack which directories \nto ignore and so on.\n\n\nWe can manually specify a configuration file to ack by using:\n```sh\nack pattern --ackrc .myconf.ackrc\n# loads the mentioned configuration file as last, so it will have a \n# higher priority\n```\n\nIf we changed our Ack configuration file `.ackrc` we can test the changes by\nexecuting a `ack --dump` and checking if our change is listed in the current\nconfiguration.\n\n\n## Using Ack with other programs\n\nWe can take advantage of ack capabilities to also replace strings with the help\nof other programs, e.g., perl or sed.\n\n\n```sh\nperl -p -i -e's/this/that/g' $(ack -f --perl)\n```\n\nor with gnu sed:\n\n```sh\nsed -i 's/oldstring/newstr/gI' $(ack -f --perl)\n```\n\nnotice that the BSD version of sed may not support the option `I` for\ncase-insensitivity.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgnebbia%2Fack_tutorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgnebbia%2Fack_tutorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgnebbia%2Fack_tutorial/lists"}