Feature Request: add "exec" option to ack

16 views
Skip to first unread message

Yagamy Light

unread,
Nov 29, 2018, 11:04:04 AM11/29/18
to ack users
I recently migrated my workflow from a mess that is grep, sed, and perl, all with different options, incompatible behavior and regexps, to just ack and perl¹. I'm happy so far, but there's one thing I miss: ability for "ack" to execute a command on files with matches. This can be worked around with xargs, e.g.:

    ack -l --print0 pattern | xargs -r0 perl -i -pe 's/pattern/replacement/g'

Unfortunately "xargs" is a limited workaround: it's kind of complex, and I afraid it may break if it match number of files more than ARG_MAX xargs variable.

It would be great if "ack" instead supported an "--exec" option to execute a command on match.

P.S.: The "contributing" says I need to post the request here first.

Bill Ricker

unread,
Nov 29, 2018, 1:31:03 PM11/29/18
to ack-...@googlegroups.com
On Thu, Nov 29, 2018 at 11:04 AM Yagamy Light <hiang...@gmail.com> wrote:
I recently migrated my workflow from a mess that is grep, sed, and perl, all with different options, incompatible behavior and regexps, to just ack and perl¹.

Sounds familiar!
I resisted Perl, being happy with awk, grep, sed, find for years; I finally moved to perl just as Perl 5.0 was supplanting Perl 4.0 back in the early/mid 90s.
I'm happy so far, but there's one thing I miss: ability for "ack" to execute a command on files with matches.
This can be worked around with xargs, e.g.:
    ack -l --print0 pattern | xargs -r0 perl -i -pe 's/pattern/replacement/g'

ack -[lgf] ... | xargs is definitely a recommended pattern for ack.
(It will actually be literally recommended in the new Ack 3.0 documentation, coming soon !)

Unfortunately "xargs" is a limited workaround: it's kind of complex,

I wouldn't say it's limited. xargs is well worth the effort to get proficient with so it rolls of the fingers.
Yes,it is different from old find(1); yes, it's taken this oldtime Unix graybeard a while to get with it, but it's worth it.

It's way less complex and more flexible than old find -exec, and bonus of it's interoperable with ack and most anything else that can stream stdout.

The separation of concerns is very much in the spirit of original Unix Shell Pipelines "Do One Thing Well" to divide the work of (commonest uses of)  find -exec
into ack -[lgf] ... | xargs .
Ack 3

(Caveat: This won't do everything find(1) did, e.g. ack doesn't do -newer or link filtering.
ack's website BeyondGrep.com and coming cookbook document when to use something else.
The corollary of "Do one thing well" is to not try to do everything. 
(BSD and GNU-Tools have sometimes forgotten that ...)
There are definitely Ack-like tasks I still use Perl one-liners for; e.g.  -000 , -a $F[2] , //xism
)

FWIW, Ack supports the same separation of concerns for itself with the -fgx options and has the same separation of concerns internally: Finding files by delving through directories (and arguments/options) and then searching text in files are in two different Perl Modules, and Andy is even working on standardizing on different vocabulary for describing the two behaviors (which I think I'm using correctly here).
(And Ack 3.0 will require separation into ack -g filepattern | ack -x  textpattern rather than having two PCRE's on one commandline as allowed, confusingly, in ack 2.x.)


and I afraid it may break if it match number of files more than ARG_MAX xargs variable.

Do not fear.
If more than -s max_chars(=128KiB or ARG_MAX) is input, xargs will run multiple commands, using no more than (not exactly)ARG_MAX chars on each.


It would be great if "ack" instead supported an "--exec" option to execute a command on match.

With the impending release of Ack 3.0, I will guarantee this won't ever be added to Ack 2.x -- we're currently debating which if any non-doc bugs are worth fixing in 2.$LAST when adding the "This is the last release" to the 2.$LAST MAN page -- and won't be in Ack 3.0,
but 3.0 feature-freeze is pretty much perfect time to start lobbying for 3.1 killer features, so well timed in a way.

As a believer in the old "Do One Thing Well" mantra, i would argue against such a change.

But Andy gets 60% of the votes so my discouragement is only advisory :-D.

P.S.: The "contributing" says I need to post the request here first.

Yes, it's always good to say hello here before trying a PULL request. 
If Andy likes an idea here or is even open to considering it, he'll ask for a feature-request bug-report.
(And it's good to know which queue to add it to ... bugs logged on Ack2 will almost certainly be WNF'd and maybe copied to Ack3, so any feature requests should go on Ack3 now.)
(Which reminds me, i need to go find/update/write an issue  ...)


Very nice!  Thank you for publishing that and sharing.

Please feel free to link ack's homepage, BeyondGrep.com from there if you like.

(If you haven't already noticed, ack switches to non-recursive implicitly when you name specific files, e.g
   ack pattern *.pl *.pm *.t   # nonrecursive
vs
   ack pattern --perl   # recursive
.)

Andy Lester

unread,
Nov 29, 2018, 4:08:59 PM11/29/18
to ack-...@googlegroups.com


On Nov 29, 2018, at 6:27 AM, Yagamy Light <hiang...@gmail.com> wrote:

I recently migrated my workflow from a mess that is grep, sed, and perl, all with different options, incompatible behavior and regexps, to just ack and perl¹. I'm happy so far, but there's one thing I miss: ability for "ack" to execute a command on files with matches. This can be worked around with xargs, e.g.:

    ack -l --print0 pattern | xargs -r0 perl -i -pe 's/pattern/replacement/g'


Sorry, no, ack won’t be adding an functionality to execute anything.  Executing based on results or doing edits to the files (another common request) are beyond what I want ack to be doing.  I want ack to be entirely read-only and to not do anything that could potentially be destructive.

Andy
Reply all
Reply to author
Forward
0 new messages