3

When using ag (edit: version 0.33.0) in a Bash while loop I can't make it show me any file names:

#!/bin/bash
cat <<__m | while read mod; do ag --nogroup --filename --ignore=local "^use $mod" ./; done
CGI
CGI::Push
__m

Output:

use 4.08;
use 4.08;
...

When executing it directly on the command line it works:

ag --nogroup --filename --ignore=local "^use CGI" ./

Output:

dir/file/ModA.pm:12:use CGI 4.08;
dir/file/ModB.pm:1:use CGI 4.08;

How can I always get the filenames inline?

MaxHQ
  • 53
  • 1
  • 6

2 Answers2

8

You could avoid using while read:

#!/bin/bash
for mod in CGI CGI::Push ; do
     ag --nogroup --filename --ignore=local "^use $mod" ./
done

I believe your problem is actually because of a bug(?) in ag. In options.c, it does:

rv = fstat(fileno(stdin), &statbuf);
if (rv == 0) {
    if (S_ISFIFO(statbuf.st_mode) || S_ISREG(statbuf.st_mode)) {
        opts.search_stream = 1;
    }
}

Since you're running under while read, your stdin is not a TTY, so opts.search_stream ends up being set to 1. This causes the opts.print_path to be set to PATH_PRINT_NOTHING. Thus, your paths won't print when run this way. Maybe ag needs an option to forcibly allow this?

eddiem
  • 1,030
  • 6
  • 9
0

As per @eddiem said, use workaround instead of while read since while read is the culprit. Well, at least the way below works fine with me. ( ag version 2.2.0 on MacOS)

IFS=$'\n'
for line in `cat $filename`; do
    ag --nogroup --numbers $line
done
exit 0

Again, thanks to @eddiem and all the credit goes to him.

Randy Lam
  • 579
  • 5
  • 11