Add examples to the ack cookbook
ack 3, currently in development, will include a cookbook of examples for folks to try. Here's an example:
Find "goats" in every file that also contains "cows"
ack -l cows | ack -x goats
What examples do you have that can get added to the cookbook? Post them here.
From @n1vux: document use of lookbehind and other useful Perl Extended RE idioms in a separate doc section (have some a few bits now but scattered)
The example I always use in presentations:
Find all the headers used in your C programs and dedupe them:
ack '#include\s+<(.+)>' --cc --output='$1' | sort -u
Pull out examples from the main ::Manual, especially the "TIPS" section.
Searching for a method call:
ack -- '->method'
or
ack '[-]>method'
Search for all the files that mention Sys::Hostname but don't match hostname. Add -I because I have --smart-case on in my .ackrc.
ack -l Sys::Hostname | ack -x -L -I hostname
Related: Find files that are using both use base and use parent.
ack 'use base' -l | ack 'use parent' -x
via @clmagic
egrep -- "\t-\t-\t-\t-\t" entries.txt |sort -k3V # Get the entries with 4+ null fields and sort the entries by IPv4 (-V) in the 3rd column.
(technically it's 4+ adjacent null fields)
Mention dirty and/or git diff --name-only.
Open list of matching files in Vim, searching for your search term:
$ ack my_search_term
<results>
$ vim $(!! -l) +/!$
!!expands to the previous command -ack my_search_termin the example$(...)expands to the output of the command in the parens, so the output ofack my_search_term -lin the xample+/<term>tells Vim to start searching for<term>once it opens!$expands to the last argument of the previous command -my_search_termin the example
Small caveat: Vim patterns and Perl regexes have some overlap, but they are different, so this doesn't work so great when you have a more complex regex as your search term.
See all the .vim files in your ~/.vim directory, except in the bundle/ directory.
ack -f --vim ~/.vim --ignore-dir=bundle
ack -g tax --ruby Finds all the ruby files that match /tax/.
vim $(ack -l taxes) open all the files that have taxes in them.
ack -f --perltest | xargs prove Find all the Perl test files and feed them to xargs which runs them all against the prove command.
We could have entire section just about ack -f and ack -g.
Find places where two methods with the same name are being called on the same line.
ack -- '->(\w+).*->\1\b'
Find all the places where I'm making a call like sort { lc $a cmp lc $b }. It gets false positive, but it's pretty useful.
ack '\bsort\b.+(\w+).+\bcmp\b.+\b(\1)\b'
Show a range of lines in a file: ack --lines=830-850 filename. And use -H to show what line numbers are.
Find modules that are not using Test::Warn:
ack -L 'warnings?_' $(ack -l Test::Warn)
Corrolary to ack -l cows | ack -x goats is ack -L cows | ack -x goats: Goats in files that do not contain cows.
Hi. I save all the outputs of ack, together with pwd and the options, using a wrapper script. When "ack" is run without any argument, these logs are shown by the pager, from the latest first.
I put the following code in my .bashrc:
function ack(){
local ackLogDir=/tmp/mylogs/Ack
mkdir -p "$ackLogDir"
chmod 777 "$ackLogDir" &> /dev/null
if [[ $# == 0 ]]; then
find "$ackLogDir" -type f | xargs ls -t |xargs less
return
fi
local f="$( mktemp --tmpdir=$ackLogDir )"
echo "# Pwd: `pwd`" > $f
echo "# ack $@" >> $f
command ack "$@" >> "$f" 2>&1
less $f
}
(Instead of PAGER, less is hardcoded.) If ack itself supplies this functionality, together with some refinement, it can be much better. (So it might be better than putting in the cookbook.)
Thanks a lot for developing ack for so long. Regards.
Find all the subroutines in Perl tests and then give a count of many of each there are:
ack '^sub (\w+)' --perltest --output='$1' -h --nogroup | sort | uniq -c | sort -n
Summarize the filetypes in your project
$ ack --noenv --show-type -f | perl -MData::Dumper -naE'++$n{$F[-1]}; END {print Dumper \%n}'
$VAR1 = {
'xml' => 32,
'sql' => 2,
'shell' => 4,
'php,shell' => 8,
'yaml' => 1809,
'php' => 7122,
'css' => 360,
'markdown' => 7,
'html' => 7,
'=>' => 1180,
'json' => 69,
'js' => 582
};
Search all the files that don't have foo and show their usage of bar. Think of a better example.
ack -L foo | ack -x -w bar
Find the most-used modules in your codebase.
ack '^use ([\w+:]+)' --output='$1' -h --nogroup | sort | uniq -c | sort -n
We could have entire section just about ack -f and ack -g.
We could. I've tried organizing a litt e more towards how user thinks ....
All the above have been added on my checkout , I'll proofread this weekend.
Meantime i'll put my WIP on github.com/n1vux/ack3.git fork, branch 26_cookbook (diff)
Current outline is below
(rendered as outline via perldoc -o markdown lib/App/Ack/Docs/Cookbook.pm | ack -h '^#', perhaps that's a cookbook recipe too ? ).
Feedback on organization welcome. I haven't sorted the middle big 'section' topically yet ...
COOKBOOK
COMPOUND QUERIES
Find "goat(s)" or "cow(s(" or both
Find "goats" in every file that also contains "cows"
find goats in files that do not contain cows
Find "goats" in every farmish file
Find "goats" and "cows" in the same line, either order, as words
Search for all the files that mention Sys::Hostname but don't match hostname.
USING ACK EFFECTIVELY
Use the .ackrc file.
Use -f for working with big codesets
Use -Q when in doubt about metacharacters
Use ack to watch log files
use ack instead of find
Searching for a method call
use -w only for words
See all the .vim files in your hidden ~/.vim directory, except in the bundle/ directory.
Finds all the ruby files that match /tax/.
Find all the Perl test files and test them
Find places where two methods with the same name are being called on the same line.
Find all the places in code there's a call like sort { lc $a cmp lc $b }.
Show a range of lines in a file
Find modules that are importing but not actually using Test::Warn
TBD these are notes to be fleshed out TBD
TBD Mention dirty and/or git diff --name-only.
TBD Search all the files that don't have foo and show their usage of bar. Think of a better example.
EXAMPLES OF --output
Find all the headers used in your C programs and dedupe them
Find the most-used modules in your codebase.
Find all the subroutines in Perl tests and then give a count of many of each there are
VERY ELEGANT ACK
Open list of matching files in Vim, searching for your search term
Extending ack your way
find log lines with 4 nulls and sort by IP address
Summarize the filetypes in your project
Fowler's Folly
KWIC: KeyWord in Context index
TBD lookahead and lookbehind
Extract part of a line from a logfile
ack '>>ip(\S+).+rq"/help' --output='$1' -h
From https://stackoverflow.com/questions/45538755/bash-text-extracting
I have this very long line of info in 1 file, and i want to extract it, so that the end result look like this output.txt ? Please help !
Input.txt
{"city":"london","first name":"peter","last name":"hansen","age":"40"},
{"city":"new york","first name":"celine","last name":"parker","age":"36"]
Output.txt
peter (40) celine (36)
The sneaky and potentially unsafe way to do it is:
ack '"first name":"([^"]+)".+"age":"(\d+)"' input.txt --output='$1 $2'
bill-n1vux #ack how is that "potentially unsafe" ?
andylester Inaccurate. Might not always work. Unsafe is wrong word Arguments might not be in that order.
bill-n1vux oh right, JSON like Perl has no guarantee of sane ordering of hash elements
I'm sure it's doable correctly with either-or and context ...
echo '[{"city":"london","first name":"peter","last name":"hansen","age":"40"}, {"city":"new york","last name":"parker","age":"36","first name":"celine"}]' \
| ack --output '$1$4($2$3)' '{.*?"first name":"([^"]*)".*?age":"(\d+)|{.*?"age":"(\d+)".*?first name":"([^"]*?)"'
peter(40)
celine(36)
(doesn't scale well to 3! or greater possible field orders to extract. at which point plain Perl with either any real JSON module or cheating any escaped quotes to Perls and EVALing into Aref of Hrefs is necessary. )
Add Elegant nearly- and not-ugly-and- exact solutions to https://github.com/beyondgrep/ack2/pull/646 that require neither hypothetical, \n as OR nor --fgrep-f .
Note: glark has greppish -f so is a partial alternative for this usecase (with <(process substitution) but glark doesn't have --passthrough so still not a full solution)
We need lots of -f and -g examples. Also, interesting that ag does not have -f. If you want ack -f with ag you have to do ag -g ""
Inventory all PHP sqldo functions
ack 'sqldo_\w+' --php -o -h | sort -u
Inventory of methods called on users:
ack 'user->(\w+)' --output='$1' -h | sort | uniq -c