Как передать переменную со списком полей для печати в 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
и т.д. из оболочки просто передать номера полей / столбцов.