1

I would like to call an awk program with n files whereas I do not know the size of n.

awk -f program.awk test1 test2 test3 ... testn

Inside the program I want to create for each file test1, test2 to testn an array.

    BEGIN{
        files = ARGC-1;
        for (i=1; i<=files; ++i){
                # here I would like to create arr1, arr2 ... arrn
        }
     }

Any idea how I can solve this?

Thanks

2 Answers 2

3

Here is what which I will come up with in GNU awk. Let's say we have file names eg: test1, test2, test3, test4 and so on. In my case I have created 8 dummy files from test1 to test8.

Now I am creating an array to print file's name, just to show here that we can have each file's index with an OUT OF THE BOX variable in GNU awk named ARGIND itself.

Here is code snippet for same(written and tested in GNU awk):

awk '
NR==1{
  print ARGC-1
}
FNR==1
{
  arr[ARGIND","FILENAME]
  nextfile
}
END{
  PROCINFO["sorted_in"]="@ind_num_asc"
  for(i in arr){
    split(i,getVal,",")
    print "Index is:"getVal[1]", Filename is:"getVal[2]
  }
}
' test*

Sample output will be as follows:

Index is:1, Filename is:test1
Index is:2, Filename is:test2
Index is:3, Filename is:test3
Index is:4, Filename is:test4
Index is:5, Filename is:test5
Index is:6, Filename is:test6
Index is:7, Filename is:test7
Index is:8, Filename is:test8

I am simply showing you how to get both index number(file whichever will be picked up by gawk it will assign it number by ARGIND as per its processing AND that file's name), once you understand this concept then you can play around more on same.

NOTE1: I am using NR==1{print ARGC-1} one ONLY to show you how that it will print how many arguments(Number of files) are passed to your awk program when we run it.

NOTE2: Also using PROCINFO["sorted_in"]="@ind_num_asc" to make sure it shows output in ascending order for indexes eg: from 1 to 2 to 3 and so on...



Explanation: Adding detailed explanation for above awk program.

awk '                                       ##Starting awk program from here.
NR==1{                                      ##Checking if its very first line of very first file.
  print ARGC-1                              ##Printing total number of files passed to it by ARGC-1.
}
FNR==1                                      ##Checking if its every file 1st line.
{
  arr[ARGIND","FILENAME]                    ##Creating array with index of ARGIND comma and filename.
  nextfile                                  ##nextfile will take program to read next file.
}
END{                                        ##Starting END block for this program from here.
  PROCINFO["sorted_in"]="@ind_num_asc"      ##Using this function to get indexes sorted.
  for(i in arr){                            ##Traversing through arr here.
    split(i,getVal,",")                     ##Splitting index into getVal array with delimiter as ,
    print "Index is:"getVal[1]", Filename is:"getVal[2] ##Printing indexes and filenames by 1st 2 elements of getVal here.
  }
}
' test*                                     ##Passing all test files into this awk program.
Sign up to request clarification or add additional context in comments.

Comments

2

If you have GNU awk (for arrays of arrays):

awk '
FNR==1 { fd++ }                 # first line of a new file increment variable fd (1st dimension index for the lines[] array)
       { lines[fd][FNR]=$0 }    # simple example of saving each line in array
' test1 test2 test3 ... testn

If you don't have GNU awk you can simulate a multi-dimensional array with something like:

awk '
FNR==1 { fd++ }
       { lines[fd FS FNR]=$0 }  # concatentate fd and FNR to form index for single-dimensional array
' test1 test2 test3 ... testn

NOTE: one downside to this approach is that to access all records for a given file (eg, fd=1) you have to scan all indexes, split them (by FS) and then test the 1st (split) field == fd=1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.