bug-gawk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: gawk skipping ./file name containing =


From: Ed Morton
Subject: Re: gawk skipping ./file name containing =
Date: Sun, 3 Oct 2021 11:17:20 -0500
User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.14.0

I just realised the NR==1 stuff I mentioned in  the `Also note that` part is just because I'm reading stdin so that part isn't a problem. I'm using cygwin btw with:

$ gawk --version
GNU Awk 5.1.0, API: 3.0 (GNU MPFR 4.1.0, GNU MP 6.2.1)


On 10/3/2021 11:02 AM, Ed Morton wrote:
I have too many files to call awk as:

   awk '{print FILENAME, $0}' *

without getting a "too many arguments" error from the shell.

To get around this I thought I could use (I know there's other workarounds, that's not the point of this email though):

   find ./ -type f -maxdepth 1 -print |
   awk 'NR==FNR{ARGV[ARGC++]=$0} {print FILENAME, $0}'

That works fine except that I have some file names that contain `=` and the contents of those are not getting printed when I expected they would since the `find` output starts every file name with `./`. To demonstrate, consider this input:

   $ head a=b file1
   ==> a=b <==
   here

   ==> file1 <==
   1
   2
   3

If I run the following I get the expected output:

   $ awk 'NR==1{for (i=1;i<ARGC;i++) printf "ARGV[%d]=%s\n", i,
   ARGV[i]; print ""} {print FILENAME, $0}' ./a=b ./file1
   ARGV[1]=./a=b
   ARGV[2]=./file1

   ./a=b here           <<< NOTE: this exists here
   ./file1 1
   ./file1 2
   ./file1 3

If I populate ARGV[] with file names from within the script it works fine:

   $ awk 'BEGIN{ARGV[ARGC++]="./a=b"; ARGV[ARGC++]="file1"} NR==1{for
   (i=1;i<ARGC;i++) printf "ARGV[%d]=%s\n", i, ARGV[i]; print ""}
   {print FILENAME, $0}'
   ARGV[1]=./a=b
   ARGV[2]=file1

   ./a=b here            <<< NOTE: this exists here too
   file1 1
   file1 2
   file1 3

but look what happens when I populate `ARGV[]` from the input:

   $ printf './%s\n' a=b file1 |
   awk 'NR==FNR{ARGV[ARGC++]=$0; next} FNR==1{for (i=1;i<ARGC;i++)
   printf "ARGV[%d]=%s\n", i, ARGV[i]; print ""} {print FILENAME, $0}'
   ARGV[1]=./a=b
   ARGV[2]=./file1

   ./file1 1         <<< NOTE: the a=b contents are missing above this line
   ./file1 2
   ./file1 3

The file `a=b` is ignored despite being stored in `ARGV[]` as `./a=b` just like if it was one of the arguments or populated manually in BEGIN.

Also note that I had to change `NR==1` to `FNR==1` for the above because if I use `NR==1` that's never executed and despite the `a=b` file contents not being printed, NR is being incremented:

   $ printf './%s\n' a=b file1 |
   awk 'NR==FNR{ARGV[ARGC++]=$0; next} NR==1{print "FOO"; for
   (i=1;i<ARGC;i++) printf "ARGV[%d]=%s\n", i, ARGV[i]; print ""}
   {print NR, FILENAME, $0}'
   3 ./file1 1
   4 ./file1 2
   5 ./file1 3

If that's not a bug, what's the explanation and how do I work around it when populating ARGV[] with a list of file names read as input?

    Ed.







reply via email to

[Prev in Thread] Current Thread [Next in Thread]