Как реализовать awk, используя переменные цикла для строки?
У меня есть файл с n строками и 4 столбцами, и я хочу прочитать содержимое 2-го и 3-го столбцов построчно. я сделал это
awk 'NR == 2 {print $2" "$3}' coords.txt
который работает, например, для второй строки. Однако я хотел бы включить этот код в цикл, чтобы я мог просматривать строку за строкой coords.txt вместо
NR == 2
Я хотел бы использовать что-то вроде
NR == i
при переходе к различным значениям i.
Я постараюсь быть яснее. Я не хочу извлекать 2-й и 3-й столбцы coords.txt. Я хочу использовать каждый элемент независимо. Например, я хотел бы иметь возможность реализовать следующий код
for (i=1; i<=20; i+=1)
awk 'NR == i {print $2" "$3}' coords.txt > auxfile
func(auxfile)
end
где func представляет все, что я хочу сделать со значением 2-го и 3-го столбцов каждой строки.
Я использую SPP, представляющий собой смесь FORTRAN и C.
Как я мог это сделать? Спасибо
3 ответа
Конечно, неэффективно вызывать awk 20 раз. Вы хотели бы вставить логику в awk, чтобы вам нужно было разобрать файл только один раз.
Однако один из способов передать переменную оболочки в awk — использовать
-v
вариант:
for ((i=1; i<20; i+=2)) # for example
do
awk -v line="$i" 'NR == line {print $2, $3}' file
done
Здесь
i
это переменная оболочки, и
line
это переменная awk.
что-то вроде этого должно работать, нет необходимости в цикле оболочки.
awk 'BEGIN {f="aux.aux"}
NR<21 {close(f); print $2,$3 > f; system("./mycmd2 "f)}' file
вызовет команду с именем временного файла для первых 20 строк, файл будет перезаписываться при каждом вызове. Конечно, если ваша функция принимает аргументы или входные данные из стандартного ввода вместо имени файла, есть более простое решение.
Здесь
./mycmd2
это исполняемый файл, который принимает имя файла в качестве аргумента. Не уверен, как вы называете свою функцию, но это достаточно общее...
Обратите также внимание на отсутствие обработки ошибок для внешних вызовов.
отвратительная система () единственный способ в awk был бы похож
system("printf \047%s\\n\047 \047" $2 "\047 \047" $3 "\047 | func \047/dev/stdin\047; ");
если упомянутая OP func() может быть напрямую вызвана GNU parallel или xargs и может принимать значения $2 + $3 в качестве $1 $2, то OP может даже сделать все это многопоточным, например
{mawk/mawk2/gawk} 'BEGIN { OFS=ORS="\0"; } { print $2, $3; } (NR==20) { exit }' file \
\
| { parallel -0 -N 2 -j 3 func | or | xargs -0 -n 2 -P 3 func }