Печать столбцов с использованием строковой переменной в AWK
Я пытаюсь использовать одну переменную в моей программе AWK (или GAWK) для печати нескольких столбцов.
Я беру столбцы для печати из командной строки:
gawk -v cols=1,2,3 -f sample.awk -F,
Я хочу иметь возможность установить эту переменную в моем BEGIN{}
заблокировать, и использовать его в основной части моей программы.
BEGIN{
split(cols, col_arr, FS)
i=1;
col_str = "$"col_arr[1];
for(col in col_arr){
if (i > 1){
col_str = col_str",$"col;
}
i++;
}
}
{
print col_str
}
Тем не менее, это будет просто напечатать "$1,$2,$3". Как я могу изменить это, чтобы напечатать столбцы 1, 2 и 3?
3 ответа
A BEGIN rule is executed once only, before the first input record is read.
Попробуйте что-то вроде этого
awk '{cols = $1 OFS $2 OFS $5; print cols}' file
Обновить
Либо вам нужно сгенерировать сценарий, подобный тому, который показал Джонатан Леффлер, поскольку в отличие от оболочки (и PERL) AWK не оценивает переменные внутри строк, или что-то вроде этого
BEGIN{
sub(/,$/,"",cols)
n=split(cols,C,/,/)
}
function _get_cols(i,s){
for(i=1;i<=n;i++) s = length(s) ? s OFS $(C[i]) : $(C[i])
return s
}
{
print _get_cols()
}
казнить
awk -v cols=2,3, -f test.awk infile
ИЛИ что-то подобное, вы должны попробовать
#!/bin/bash
# Usage : _parse <FS> <OFS> 1 2 3 ... n < file
_parse()
{
local fs="$1"
local ofs="$2"
shift 2
local _s=
local f
for f; do
_s="${_s}\$${f},"
done
awk -F"$fs" -v OFS="$ofs" "{ print ${_s%,} }"
}
# Call function
_parse ' ' '\t' 1 3 < infile
Вы, вероятно, лучше всего использовать программу (может быть, awk
) написать awk
Скрипт, который вы в конечном итоге запустите
Например:
trap "rm -f script.awk; exit 1" 0 1 2 3 13 15
awk '{ printf "{ print ";
pad = ""; for (i = 1; i <= NF; i++) { printf "%s$%d", pad, $i; pad = ", " }
print " }"
}' <<< "1 2 5" > script.awk
awk -f script.awk data.file
rm -f script.awk
trap 0
Столбцы, которые должны быть напечатаны, отображаются в виде строки здесь, функции Bash, но могут быть получены из файла или из других источников по мере необходимости. trap
Команды являются сценарием оболочки, который гарантирует, что временный файл, script.awk
, устранен. Может быть, лучше внедрить идентификатор процесса в имя, чтобы обеспечить уникальность, если сценарий запускается одновременно. Если вы действительно беспокоитесь об этом, используйте mktemp
или аналогичная программа для создания более сложного угадываемого имени. Не требуется, чтобы файл скрипта заканчивался на .awk
; он просто дает понять, что в нем содержится, если вы обнаружите, что он лежит вокруг.
Вот как это сделать без циклов или массивов:
jot -s '' -c - 65 126 |
mawk -f <( mawk -v __='3,59,8,42,17,39' ' BEGIN { OFS =(FS = ",")"$" $(ORS = _) = __ print "{ print $" ($!(NF=NF) ) " } " }' ) FS= OFS='\f'
C
{
H
j
Q
g
что происходит в подпроцессеawk
call жестко кодирует необходимые столбцы, генерируя этот код на лету:
# gawk profile, created Mon Jan 16 18:27:35 2023
# Rule(s)
1 {
1 print $3, $59, $8, $42, $17, $39
}