Как передать переменную со списком полей для печати в awk?

Я хотел бы иметь список полей, например '$1, $2', в переменной "dc". Переменная передается в awk, но не работает, как я ожидал.

$ dc='$1, $2'          # variable with list of fields
$ fff="%-3s %-3s\n"    # format


$ echo "1 2 3 4 5"|awk -v fff="$fff" -v dc="$dc" '{printf fff, $1, $2}'     ### OK
1   2                      

$ echo "1 2 3 4 5"|awk -v fff="$fff" -v dc="$dc" '{printf fff, dc}'         ### NOT OK
  awk: (FILENAME=- FNR=1) fatal: not enough arguments to satisfy format string
          `%-3s %-3s
  '
            ^ ran out for this one

2 ответа

Единственный способ сделать то, что вы просите, не добавляя много сложности, - это вернуться обратно в оболочку, чтобы развернуть dc:

$ echo "1 2 3 4 5"|awk -v fff="$fff" '{printf fff, '"$dc"'}'
1   2

но за 30 с лишним лет программирования под UNIX и за 20 с лишним лет использования awk я никогда не сталкивался с ситуацией, когда такой подход был бы наилучшим, поэтому, если вы расскажете нам больше о том, что вы делаете, мы, вероятно, предложим гораздо лучшую альтернативу,

Подумайте об этом - в хорошо спроектированной программе вы сможете заменить весь свой awk-скрипт на C-программу или что-то еще в будущем без изменений в интерфейсе или вызывающем коде. Это было бы невозможно с вашим текущим подходом, поэтому ваше программное обеспечение тесно связано, что крайне нежелательно.

Вот пример альтернативы:

$ dc='1 2'
$ fff="%-3s"
$ echo "1 2 3 4 5"|awk -v fff="$fff" -vdc="$dc" 'BEGIN{n=split(dc,dcA)} {for (i=1; i<=n; i++) printf fff, $dcA[i] (i<n?FS:RS) }'
1   2

Это, вероятно, все еще не лучший подход, но, возможно, он даст вам возможность подумать.

В awk вы не можете хранить $1, $2, $3 и т.д. в переменной строки, как вы пытаетесь сделать. $ здесь оператор, который основан на целочисленном значении n рядом с ним представляет n-th столбец из ввода.

Вы можете сделать что-то вроде этого, если хотите:

echo "1 2 3 4 5"|awk -v fff="$fff" -v p="1" -v q="2" '{printf fff, $p, $q}'
1   2  

Это скорее, чем пройти $1, $2 и т.д. из оболочки просто передать номера полей / столбцов.

Другие вопросы по тегам