I find this situation to be a very large drawback to using Perl. While this answer is suboptimal, performance-wise, and only fits situations involving xargs
, I've typically found it the workaround I use 95% of the time. So the problem scenario:
git ls-files -z | xargs -0 perl -ne 'print "$ARGV:$.\t$_" if /#define oom/'
file.h:85806 #define oom() exit(-1)
That line number is obviously not correct, and you'll obviously get the same behavior with find
Of course, with this regex, or other simpler Perl regexes, I'd just use awk
or git grep -P
. However, if you're dealing with a fairly complicated regular expression, or need other Perl features, that won't work...and the correct answers to this question further complicate what is already likely to be a complicated Perl one-liner.
So I just use the following:
git ls-files -z | xargs -0 -n1 perl -ne 'print "$ARGV:$.\t$_" if /#define oom/'
file.h:43 #define oom() exit(-1)
The -n1
xargs argument causes xargs to kick off a Perl process for each file, which results in the correct line numbers. You're looking at very significant performance impact, but I've found it acceptable for very large projects with millions of lines of code vs. solving it in Perl, which I find almost always requires an actual script vs. a one-liner. It is not acceptable for system-wide searches in the vast majority of cases.