Я хотел бы вызвать программу awk с n файлами, тогда как я не знаю размер n.
awk -f program.awk test1 test2 test3 ... testn
Внутри программы я хочу создать для каждого файла test1, test2 для testn массив.
BEGIN{
files = ARGC-1;
for (i=1; i<=files; ++i){
# here I would like to create arr1, arr2 ... arrn
}
}
Есть идеи, как я могу это решить?
Спасибо
Если у вас есть GNU awk
(для массивов массивов):
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
Если у вас нет GNU awk
, вы можете смоделировать многомерный массив с помощью чего-то вроде:
awk '
FNR==1 { fd++ }
{ lines[fd FS FNR]=$0 } # concatentate fd and FNR to form index for single-dimensional array
' test1 test2 test3 ... testn
ПРИМЕЧАНИЕ: Один недостаток этого подхода заключается в том, что для доступа ко всем записям для данного файла (например, fd=1
) вам нужно просмотреть все индексы, разделить их (по FS
), а затем проверить 1-е (разделенное) поле == fd=1
Вот что я придумаю в GNU awk
. Допустим, у нас есть имена файлов, например: test1
, test2
, test3
, test4
и так далее. В моем случае я создал 8 фиктивных файлов от test1 до test8.
Теперь я создаю массив для печати имени файла, просто чтобы показать здесь, что мы можем иметь индекс каждого файла с переменной ИЗ КОРОБКИ в GNU awk
с именем ARGIND
.
Вот фрагмент кода для того же (написан и протестирован в 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*
Пример вывода будет следующим:
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
Я просто показываю вам, как получить как номер индекса (файл, который будет выбран gawk, он присвоит ему номер ARGIND в соответствии с его обработкой, так и имя этого файла), как только вы поймете эту концепцию, вы можете больше поиграть с тем же .
ПРИМЕЧАНИЕ1: Я использую NR==1{print ARGC-1}
один ТОЛЬКО, чтобы показать вам, как он будет печатать, сколько аргументов (количество файлов) передается вашей awk
программе, когда мы ее запускаем.
ЗАМЕТКА 2: Также используйте PROCINFO["sorted_in"] = "@ind_num_asc"
, чтобы убедиться, что вывод отображается в порядке возрастания для индексов, например: от 1 до 2, до 3 и так далее...
Объяснение: Добавление подробного объяснения к вышеуказанной awk
программе.
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.