Как программно определить вкус awk (например, gawk vs nawk)


8

Я использую приложение командной строки, которое по сути представляет собой набор сценариев оболочки bash. Приложение было написано для запуска на BSD / OSX, а также на Linux. Один из скриптов опирается на awk. Он содержит две команды awk: одна написана для nawk (стандартная реализация BSD awk) и одна написана для gawk (реализация GNU awk).

Эти две команды awk не совместимы с различными средами; в частности, команда nawk не выполняется при запуске с gawk. Сценарий проверяет имя ядра (т.е. uname -s), чтобы определить среду хоста, а затем запускает соответствующую команду awk. Однако я предпочитаю работать на Mac OS X с установленными основными утилитами GNU, поэтому скрипт не запускается правильно.

В процессе размышлений о том, как лучше всего исправить эту ошибку, мне пришло в голову, что было бы неплохо узнать, как программно различать различные варианты общих утилит командной строки, предпочтительно относительно надежным и переносимым способом.

Я заметил, что nawk не принимает флаг '-V' для печати информации о версии, поэтому я подумал, что что-то вроде следующего должно работать:

awk -V &>/dev/null && echo gawk || echo nawk

Другой вариант может быть:

awk -Wversion &>/dev/null && echo gawk || echo nawk

Кажется, это работает в двух моих средах тестирования (OS X и CentOS). Вот мои вопросы:

  • Это лучший путь?
  • Есть ли способ расширить это для обработки других вариаций awk (например, mawk, jawk и т. Д.)?
  • Стоит ли беспокоиться о других версиях awk?

Я должен также упомянуть, что я знаю очень мало о awk.


Если команда awk не очень сложна, или даже если это так, вы можете подумать о переносе ее на perl или что-то еще, что унифицировано.
Wildcard

Давайте посмотрим на версию awk awk -Wvвместо среды хоста
Costas

1
Мой awk очень слабый, но я считаю, что это довольно просто. Я фактически уже переписал это в чистом bash. Но это одна из тех ситуаций, когда меня больше интересует удовлетворение моего любопытства, чем реальное решение исходной проблемы.
igal

@ Costas Что-то подобное действительно происходило со мной, но я не был уверен, насколько хрупким оно может быть; Я очень мало знаю о awk. Я добавил свое текущее решение в свой пост.
igal

1
Одна альтернатива - игнорировать, какая версия awkиспользуется, и вместо этого кодировать в спецификацию POSIX .
chepner

Ответы:


7
if awk --version 2>&1 | grep -q "GNU Awk"
then
    awk 'BEGIN {print "I am GNU Awk"}'

elif awk -Wv 2>&1 | grep -q "mawk"
then
    awk 'BEGIN {print "I am mawk"}'

else
    awk 'BEGIN {print "I might be nawk, might not be"}'
fi

В качестве альтернативы test is awk является символической ссылкой:

awk=$( command -v awk )
[[ -L $awk ]] && readlink $awk # make some decision about the result of that

Это хорошо ... но есть несколько вариантов (трудно различимых) для старых-awk, nawk и более новых версий BWK. Для них может быть адаптирован пример сценария .
Томас Дики

3

Попробуйте использовать whichкоманду и используйте ее код выхода.

which nawk
if [[ $? == 0 ]]; then
    command="nawk"
else
    command="gawk"
fi

затем отформатируйте ваш скрипт, чтобы использовать переменную в качестве команды

$command '{print $1}` 

будет читаться как

nawk '{print $1}`

если whichнайдет nawk. В противном случае это будет использоватьgawk


1
Так как commandэто встроенная bash, вы можете использовать другое имя для своей переменной, и вы также можете увидеть невероятно подробный ответ о том, почему для многих оболочек есть лучшие альтернативы whichна unix.stackexchange.com/a/85250/109842
Эрик Ренуф

1

GNU Awk часто устанавливается как gawk, с awkкак символическая ссылка на него в системах , где GNU является по умолчанию. Я полагаю, что это относится к системам BSD и OS X, поскольку они уже есть свои awk.

if gawk '{ exit; }' < /dev/null 2> /dev/null
then
    echo "gawk available"
else
    echo "gawk not available"
fi

Спасибо за ваш вклад. Это хорошая идея, и вы правы, что это относится ко мне на OS X. Но я надеялся, что, так сказать, внутреннее решение.
igal

0

Грязный хак

if nawk 'BEGIN { nawk-only-function() ;}' 
then 
   nawk -f nfile.awk ...
else 
   gawk -f gfile.awk ...
fi
  • где nawk-only-function() существуют только наnawk

-2

Я, вероятно, попытался бы использовать макрос AC_PROG_AWK m4 в autoconf, чтобы выбрать один из них, упорядочив их соответствующим образом. Это, вероятно, излишне, хотя


Не могли бы вы отредактировать, чтобы предоставить немного больше информации о том, как вы будете использовать этот макрос для этого сценария?
Майкл Гомер

На самом деле он не сообщает, какую из них он нашел, а просто ищет реализации awk и выбирает одну на основе своего имени.
Томас Дики
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.