Как (специфичную) команду awk можно использовать в make с сохранением результата в переменной? - PullRequest
1 голос
/ 20 сентября 2011

Я пробовал два метода.A) использование функции оболочки make и B) установка переменной окружения.Оба метода сталкиваются с проблемой экранирования.

Грубо говоря, команда, которую я пытаюсь запустить в make-файле:

awk '{if ( $0 !~ /^#/ ) print $2 }' data.dat | tail -1

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

РЕДАКТИРОВАТЬ: После попытки предложения ниже, кажется, что проблема является более фундаментальной, чем просто восклицательный знак.Новый меньший тестовый пример - что-то вроде

 awk '{ print $2 }' data.dat | tail -1

, где я предполагаю, что файл не имеет комментариев.Виновниками стали апострофы или то, что я использую канал UNIX в make.

EDIT 2: Половина решения ... Я забыл использовать $$ для $ в make.Надеюсь, это позволит мне опубликовать решение.

РЕДАКТИРОВАТЬ 3: Похоже, способ разбора скобок в make во время определения переменных make, запрещает использование команд, вызванных функцией оболочки, которая их использовала.По сути, это означает, что однострочники gawk не могут быть использованы из make, если кто-то хочет сохранить результаты.

Ответы [ 3 ]

1 голос
/ 20 сентября 2011

Вы можете переписать свой reg-exp, чтобы переместиться туда, где имеет место отрицание, то есть

awk '{if ( $0 ~ /^[^#]/ ) print $2 }' data.dat | tail -1
       # -----^^^^^^^^

, где указано совпадение с любым $ 0 (строка), где первый символ НЕ является символом "#".

Возможно, у вас возникли другие проблемы, потому что вы используете make.

Если это не решит вашу проблему, отредактируйте ваш пост, указав версию ОС, значение $SHELL, версию, есливозможно и gmake или make правил.ТАКЖЕ скопируйте / вставьте соответствующие сообщения об ошибках, которые вы получаете.

Надеюсь, это поможет.

1 голос
/ 22 сентября 2011

Почему-то мне не хватает области, где в Makefile вы пытаетесь установить переменную. Как вы уже заметили, вы столкнулись с несколькими проблемами.

Когда вы думаете о make (1) и о том, как он обрабатывает переменные, вы должны думать о нем как о макропроцессоре (в отличие от ожидаемого поведения, похожего на оболочку). Например, следующий Makefile

A = HEHE
B = HOHO
C = $A $B
A = HAHA

default:
        echo $C

производит вывод "HAHA HOHO", тогда как программист оболочки ожидает "HEHE HOHO". Так что «позже» - это несколько вводящий в заблуждение термин с Makefiles.

Конечно, вы можете вызывать команды оболочки в правилах, но имейте в виду: каждая строка в правиле выполняется в своем собственном процессе оболочки, поэтому, даже если вы установите переменную (Shell-), она будет потеряна в следующей командной строке.

Мои рекомендации:

  • Если вам действительно нужно сохранить промежуточные значения, используйте временные файлы.

  • Если вам нужно кодировать сложные команды оболочки, поместите их в отдельный файл сценария

Конечно, можно использовать продолжение строки (\ в конце строки) и расширенное использование escape-кавычек для кодирования сложных конструкций оболочки в Makefile, и многие люди так делают - но это не то, что было разработано make (1) for - Получающиеся сценарии ужасны для чтения, и поиск ошибок или неправильного поведения является утомительной задачей.

1 голос
/ 20 сентября 2011

Это не совсем отвечает на ваш вопрос, но я думаю, что вы можете обойти awk с

grep -v "^#" | cut -f 2 | tail -n 1
...