website icon indicating copy to clipboard operation
website copied to clipboard

Add examples to the ack cookbook

Open petdance opened this issue 8 years ago • 51 comments

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.

petdance avatar Mar 28 '17 05:03 petdance

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)

petdance avatar Mar 28 '17 05:03 petdance

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

petdance avatar Mar 28 '17 05:03 petdance

Pull out examples from the main ::Manual, especially the "TIPS" section.

petdance avatar Mar 30 '17 17:03 petdance

Searching for a method call:

ack -- '->method'

or

ack '[-]>method'

petdance avatar Apr 04 '17 16:04 petdance

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

petdance avatar Apr 05 '17 21:04 petdance

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)

n1vux avatar Apr 14 '17 17:04 n1vux

Mention dirty and/or git diff --name-only.

petdance avatar Apr 20 '17 14:04 petdance

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_term in the example
  • $(...) expands to the output of the command in the parens, so the output of ack my_search_term -l in the xample
  • +/<term> tells Vim to start searching for <term> once it opens
  • !$ expands to the last argument of the previous command - my_search_term in 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.

hoelzro avatar Apr 20 '17 14:04 hoelzro

See all the .vim files in your ~/.vim directory, except in the bundle/ directory.

ack -f --vim ~/.vim --ignore-dir=bundle

petdance avatar Apr 30 '17 23:04 petdance

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.

petdance avatar May 02 '17 15:05 petdance

We could have entire section just about ack -f and ack -g.

petdance avatar May 02 '17 15:05 petdance

Find places where two methods with the same name are being called on the same line.

ack -- '->(\w+).*->\1\b'

petdance avatar May 11 '17 18:05 petdance

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'

petdance avatar May 12 '17 15:05 petdance

Show a range of lines in a file: ack --lines=830-850 filename. And use -H to show what line numbers are.

petdance avatar May 15 '17 15:05 petdance

Find modules that are not using Test::Warn:

ack -L 'warnings?_' $(ack -l Test::Warn)

petdance avatar May 15 '17 19:05 petdance

Corrolary to ack -l cows | ack -x goats is ack -L cows | ack -x goats: Goats in files that do not contain cows.

petdance avatar May 19 '17 15:05 petdance

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.

teika-kazura avatar Jun 17 '17 12:06 teika-kazura

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

petdance avatar Jun 22 '17 18:06 petdance

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
        };

petdance avatar Jun 26 '17 03:06 petdance

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

petdance avatar Jun 29 '17 19:06 petdance

Find the most-used modules in your codebase.

ack '^use ([\w+:]+)' --output='$1' -h --nogroup | sort | uniq -c  | sort -n

petdance avatar Jul 10 '17 16:07 petdance

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 ....

n1vux avatar Jul 29 '17 04:07 n1vux

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

n1vux avatar Jul 29 '17 05:07 n1vux

Extract part of a line from a logfile

ack '>>ip(\S+).+rq"/help' --output='$1' -h

petdance avatar Aug 01 '17 18:08 petdance

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' 

petdance avatar Aug 07 '17 03:08 petdance

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. )

n1vux avatar Aug 07 '17 16:08 n1vux

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)

n1vux avatar Aug 10 '17 19:08 n1vux

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 ""

petdance avatar Sep 01 '17 14:09 petdance

Inventory all PHP sqldo functions

ack 'sqldo_\w+' --php -o -h | sort -u

petdance avatar Sep 01 '17 19:09 petdance

Inventory of methods called on users:

ack 'user->(\w+)' --output='$1' -h | sort | uniq -c

petdance avatar Sep 07 '17 15:09 petdance