Как оценить условия, переданные в awk?

#performance #awk

#Производительность #awk

Вопрос:

Скрипт, написанный на Bash, передает аргументы в Awk, такие как sample_name==10 .

Затем Awk находит, какому столбцу в таблице соответствует sample_name , и переписывает аргумент, соответствующий левой части выражения, например as $1 == 10 .

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

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

  for (c in where_col) {
      ((where_math[c] == "==" amp;amp; $where_idx[c] == where_val[c]) ||
      (where_math[c] == ">=" amp;amp; $where_idx[c] >= where_val[c]) ||
      (where_math[c] == "<=" amp;amp; $where_idx[c] <= where_val[c]) ||
      (where_math[c] == "!=" amp;amp; $where_idx[c] != where_val[c]) ||
      (where_math[c] == ">"  amp;amp; $where_idx[c] >  where_val[c]) ||
      (where_math[c] == "~"  amp;amp; $where_idx[c] ~  where_val[c]) ||
      (where_math[c] == "<"  amp;amp; $where_idx[c] <  where_val[c])) {
        #some action
      }
  

Хотя сейчас это работает, я ищу способ сделать это более чисто.

Комментарии:

1. что такое where_math содержимое?

2. Это просто операторы условий, подобные == , поэтому в настоящее время говорится, что если оператор является == , то используйте ==

3. Я бы попытался решить это, но мне нужно больше контекста

4. Я просто пытаюсь оценить условный оператор, сохраненный как переменная. Если содержимое a сохранено как 1==1 , я бы хотел сказать что-то вроде if(a) , чтобы оценить значение true.

Ответ №1:

Вероятно, вы бы сделали это с помощью метапрограммирования:

Вы должны сгенерировать скрипт awk для выполнения. Дополнительный шаг расширения переменной позволяет вставить, например, <= в код. Но это требует дополнительных размышлений о надежности, поскольку вы не хотите разрешать генерацию недопустимых или небезопасных сценариев.

Вероятно, вы можете легко сделать это онлайн с помощью here-doc в bash.

Ответ №2:

В Awk нет функции типа eval, которую вы ищете, но (как вы делаете) ее можно использовать для написания средства оценки.

Может быть, что-то вроде написания этого с помощью языка, а не на языке language, приблизит вас.
В противном случае я не уверен, что awk — это ваш путь наименьшего сопротивления

 awk -v "lhs=$lhs" -v "op=$op" -v "rhs=$rhs"

op == "==" {result = lhs == rhs}
op == ">=" {result = lhs >= rhs}
op == "<=" {result = lhs <= rhs}
op == "!=" {result = lhs != rhs}
op == ">"  {result = lhs > rhs}
op == "~"  {result = lhs ~ rhs}
op == "<"  {result = lhs < rhs}

END{ #some action involving result
}