Печать столбцов с использованием строковой переменной в 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

что происходит в подпроцессеawkcall жестко кодирует необходимые столбцы, генерируя этот код на лету:

      # gawk profile, created Mon Jan 16 18:27:35 2023

# Rule(s)

 1  {
 1      print $3, $59, $8, $42, $17, $39
}
Другие вопросы по тегам