Хобрук: Ваш путь к мастерству в программировании

Проблемы с AWK и мощностью (DD-WRT)

Я пытаюсь извлечь сумму чисел в переменную (cwr) в файле (wa_cidr) с помощью этой команды:

cwr=$(grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$" /tmp/wa_cidr | awk -F '/' '`{n += 2**(32 - $NF)}` END {print n}')

Однако вывод пустой.

Если я поменяю часть...

{n += 2**(32 - $NF)} 

To...

{n += (32 - $NF)} 

Я получаю действительный результат, записанный в переменную cwr.

Казалось бы, я не могу использовать силу (32 - $NF), используя 2**X или 2^X в AWK.

Если я сделаю это в командной строке, например. с использованием...

$ echo $(2**5)

Нет проблем, и результат равен 32.

Я пробовал много вариантов формулы (круглые скобки и т. д.), но ничего не работает.

Что не так? Можно ли это сделать другим способом?

Спасибо, Сорен.

29.10.2016

  • Пожалуйста, покажите нам пример строки ввода, которая создает симптом, который вы описываете. 29.10.2016
  • Кроме того, я предполагаю, что вы имели в виду awk 'BEGIN { print 2**5 }' как интерактивный тест (в оболочке вам нужно было бы выполнить echo $((2**5)) ($((...)) для арифметических расширений), но здесь это не имеет значения, учитывая, что ваша проблема связана с Awk скрипт). 29.10.2016
  • Мне было бы интересно узнать, почему вы используете мощность на коробке DD-WRT? Спасибо, что поделились (если можно). Решение ниже, безусловно, правильное. Удачи. 30.10.2016
  • @shellter — см. ниже и здесь: dd-wrt.com/phpBB2/ viewtopic.php?p=1051848 30.10.2016
  • @mklement0 - эта строка ´grep -E ^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1- 2][0-9]|3[0-2]))?$ /tmp/wa_cidr | awk -F '/' '{n += (32 - $NF)} END {print n}'` дает вывод '524', но эта строка grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$" /tmp/wa_cidr | awk -F '/' '{n += 2^(32 - $NF)} END {print n}' дает пустой вывод. Даже если 32 - $NF равно нулю (не может быть отрицательным), результатом будет 1. Может быть, мне нужен параметр команды, чтобы активировать расширенные вычисления или что-то в этом роде? 30.10.2016
  • Кстати, точно такой же расчет в Excel дает результат 524 до степени и 3996 после - сумма (32-$NF) = 524/сумма 2^(32-$NF) = 3996... 30.10.2016
  • Не удается выполнить одиночный расчет? Пожалуйста, добавьте любые пояснения и, в идеале, образец входных данных, демонстрирующий проблему непосредственно к вашему ответу. 30.10.2016

Ответы:


1

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

cwr=$(awk -F'/' '/^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$/{n += 2^(32 - $NF)} END {print n+0}' /tmp/wa_cidr)
29.10.2016
  • Хм, похоже, что так и должно быть, но я получаю эту ошибку: Stopped (tty input) Я думаю, что в оболочке DD-WRT могут быть некоторые ограничения, но я не понимаю, почему простой расчет может вызвать проблемы. Чтобы уточнить: я пытаюсь извлечь CIDR из файла wa_cidr, получить число после косой черты (например, IP/30), вычислить количество IP-адресов в этом сегменте и вернуть результат в $cwr. Это работает с моей командой, за исключением того, что я не могу правильно рассчитать (степень) с этим числом. Я вижу, что ваш код лучше, но теперь я получаю эту ошибку...? Спасибо, Сорен. 30.10.2016
  • Это была опечатка, я бы поставил имя файла после последней ), а не перед ней. Исправлено сейчас. Это одна из причин, по которой в ваших интересах всегда предоставлять проверяемый образец ввода/вывода при публикации вопроса (т. е. минимально воспроизводимый пример), потому что без него мы не сможем протестировать потенциальное решение перед его публикацией. 30.10.2016

  • 2

    Хм, похоже, я что-то напутал, когда упомянул, что что-то ограничено в оболочке DD-WRT.

    Согласно этому веб-сайту, https://rosettacode.org/wiki/Exponentiation_operator#awk, " традиционные реализации awk не предоставляют оператора экспоненты, поэтому мы определяем функцию для вычисления экспоненты».

    Итак, чтобы код работал, он должен выглядеть примерно так:

    cwr=$(grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$" /tmp/wa_cidr | awk -F '/' 'function pow(x,n){r=1;for(i=0;i<n;i++)r=r*x;return r}{c += pow(2,(32-$NF))} END {print c}')
    

    Что дает правильное значение 3996.

    Спасибо всем за участие!

    /Сорен

    30.10.2016
    Новые материалы

    Декларативное и функциональное программирование в стиле LINQ с использованием JavaScript с использованием каррирования и генератора ...
    LINQ - одна из лучших функций C #, которая обеспечивает элегантный способ написания кода декларативного и функционального стиля, который легко читать и понимать. Благодаря таким функциям ES6,..

    Структуры данных в C ++ - Часть 1
    Реализация общих структур данных в C ++ C ++ - это расширение языка программирования C, которое поддерживает создание классов, поэтому оно известно как C с классами . Он используется для..

    Как я опубликовал свое первое приложение в App Store в 13 лет
    Как все началось Все началось три года назад летом после моего четвертого класса в начальной школе. Для меня, четвертого класса, лето кажется бесконечным, пока оно не закончится, и мой отец..

    Что в лицо
    Очерк о возвращении физиогномики и о том, почему мы должны это приветствовать. История начинается со странной науки. Р. Тора Бьорнсдоттир, Николас О. Рул. Видимость социального класса по..

    Почему шаблоны проектирования и почему нет?
    Сложность — мать всех проблем в программировании. Программное обеспечение должно быть разработано с точки зрения того, кто его поддерживает, а не того, кто его пишет, потому что программное..

    Создание дизайна обуви с помощью машинного обучения
    Обувь. Что подождать? Я думал, что речь пойдет о машинном обучении! Ну это так. Если бы вы пошли на Amazon, сколько обуви вы бы нашли? Наверное, много, не так ли? Но много ли в них..

    GraalVM в 2022 году: итоги года
    2022 год был очень продуктивным для проекта и сообщества GraalVM. Вместе мы разработали множество новых функций, выпустили GraalVM для последних версий Java и новых платформ и увидели несколько..